我是rails和构建关系数据库应用程序的新手。
我有一个有点复杂的数据库结构,我正在尝试创建一个创建子对象的嵌套表单,然后通过habtm关系将该子对象与现有对象相关联。
我的目标是尽可能精简地将数据输入此数据库。我使用Railscast#196-197来实现这一目标。
部分数据库结构:
类别< - habtm - >服务< - belongs_to - >提供者
类别有很多服务,服务可能有很多类别。
提供商拥有许多服务,服务属于单一提供商。
提供商可能拥有许多不同类别的服务。
模特:
class Provider < ActiveRecord::Base
has_many :services, :dependent => :destroy
accepts_nested_attributes_for :services, allow_destroy: true
end
class Service < ActiveRecord::Base
belongs_to :provider
has_and_belongs_to_many :categories
has_many :comments
end
我有一个嵌套表单,允许我从添加提供程序的同一表单中添加服务。
我还生成了一个类别列表(复选框),以允许用户将服务与类别相关联。
问题是,当我提交表单时,没有创建services_categories的连接表。
这是我在提交“创建提供商”表单时收到的来自控制台的信息。我可以看到category_ids []的存储位置,但它们不会被传递到任何地方,并且它们不会在连接表中启动条目的创建。
控制台打印输出:
Started POST "/providers" for ::1 at 2015-05-06 14:38:36 -0700
Processing by ProvidersController#create as HTML
Parameters: {"utf8"=>"√", "authenticity_token"=>"MJXUbLeh+pT3OSC6B2pfGnsUOBkG1
jim2GUpKD9KC72vp3trLAc4Zf+ICZ6yGLiagTGQXMsJ/j8iDpbpCBhUxQ==", "provider"=>{"name
"=>".Test Provider", "organization"=>".Test Organization", "contact"=>"", "phone
"=>"", "website"=>"", "address1"=>"", "address2"=>"", "city"=>"", "state"=>"Onli
ne", "zip"=>"", "services_attributes"=>{"0"=>{"title"=>".Test Service", "descrip
tion"=>"", "_destroy"=>"0"}}}, "category"=>{"service_ids"=>[""]}, "service"=>{"c
ategory_ids"=>["4", "37", "36"]}, "commit"=>"Create Provider"}
(0.0ms) begin transaction
SQL (2.0ms) INSERT INTO "providers" ("name", "organization", "address1", "add
ress2", "city", "state", "phone", "website", "contact", "created_at", "updated_a
t") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) [["name", ".Test Provider"], ["org
anization", ".Test Organization"], ["address1", ""], ["address2", ""], ["city",
""], ["state", "Online"], ["phone", ""], ["website", ""], ["contact", ""], ["cre
ated_at", "2015-05-06 21:38:36.715129"], ["updated_at", "2015-05-06 21:38:36.715
129"]]
SQL (0.0ms) INSERT INTO "services" ("title", "description", "provider_id", "c
reated_at", "updated_at") VALUES (?, ?, ?, ?, ?) [["title", ".Test Service"], [
"description", ""], ["provider_id", 56], ["created_at", "2015-05-06 21:38:36.731
130"], ["updated_at", "2015-05-06 21:38:36.731130"]]
(39.0ms) commit transaction
Redirected to http://localhost:3000/providers/56
Completed 302 Found in 84ms (ActiveRecord: 41.0ms)
我的providers_controller.rb(已取出一些不相关的部分):
class ProvidersController < ApplicationController
###
def new
@provider = Provider.new
@provider.services.build
@services = Service.all
@service = Service.new
end
def edit
@provider = Provider.find(params[:id])
end
def create
@provider = Provider.new(provider_params)
if @provider.save
redirect_to @provider
else
render 'new'
end
end
###
def get_all_categories
@categories = Category.find(:all, :order => 'name')
end
private
def provider_params
params.require(:provider).permit(:name, :organization, :address1, :address2, :city, :state, :zip, :phone, :website, :contact, :service_ids => [], services_attributes: [:id, :title, :description, :_destroy, :category_ids => []])
end
end
如您所见,属性:category_ids =&gt; []未显示在控制台的服务属性列表中。
我用于提交提供商数据的表单的相关部分:
<%= form_for @provider do |f| %>
<%= f.fields_for :services do |builder| %>
<%= render "services_fields", :f => builder %>
<% end %>
<%= f.submit %>
添加新服务的部分格式:
<%= f.label :title, "Service Title" %><br/>
<%= f.text_field :title %> <br/>
<%= f.label :description, "Service Description" %><br/>
<%= f.text_area :description, :rows => 3 %> <br/>
<p>
<label>Associated Categories</label>
<p>
<label>Associated Categories</label>
<div>
<%= hidden_field_tag "category[service_ids][]", nil %>
<% Category.all.sort_by{|category| category.name}.each do |category| %>
<%= check_box_tag "service[category_ids][]", category.id,
@service.categories.include?(category), id: dom_id(category) %>
<%= label_tag dom_id(category), category.name %></br>
</div>
<% end %>
</p>
<%= f.check_box :_destroy %>
<%= f.label :_destroy, "Remove Service" %><br/>
我对你能想到的任何方式感兴趣
所有形式。
我想过有一个弹出窗口可以将用户带到原始的Add Service表单,该表单关联了Categories,但我是Rails的新手,我不知道会有多难。 我也觉得我应该能够在一个页面上完成所有这些工作。
我非常关注服务和类别之间的关系。它适用于应用程序的所有其他部分。
如果我可以发布任何其他相关的代码段,请告诉我。 谢谢!
答案 0 :(得分:0)
属性:category_ids =&gt; []并未显示在控制台中的服务属性列表中,因为params["provider"]["service_attributes"],
它位于params["service"]
内部params["provider"]["service_attributes"]
1}}。
这意味着创建操作无法访问category_ids。
如果要在不修改表单的情况下关联创建的服务和类别,可以尝试引用新创建的服务,然后使用&#39; params [&#34; service&#34;]&#39;更新其category_ids。 ,或者在创建提供者之前将category_id添加到params["provider"]["service_attributes"]["category_ids"] = params["service"]["category_ids"]
中:
{{1}}
虽然这需要您将params中允许的属性重新列入白名单。
或者您可以修改表单,以便category_ids最终嵌套在params哈希中的service_attributes中。