Tim*_* T. 5 ruby-on-rails has-many-through aggregation
编辑我的问题以简明扼要并更新我所做的事情:
如何为公司建立多个地址并为联系人分配单个地址,并在创建或编辑联系人时分配这些地址?
我想使用嵌套属性来创建新联系人时添加地址.该地址作为自己的模型存在,因为我可能希望选项从现有地址下拉而不是从头开始.
我似乎无法让它发挥作用.我得到一个未定义的方法`build'为nil:NilClass错误
这是我的联系人模型:
class Contact < ActiveRecord::Base
attr_accessible :first_name, :last_name, :title, :phone, :fax, :email, :company,
:date_entered, :campaign_id, :company_name, :address_id, :address_attributes
belongs_to :company
belongs_to :address
accepts_nested_attributes_for :address
end
Run Code Online (Sandbox Code Playgroud)
这是我的地址模型:
class Address < ActiveRecord::Base
attr_accessible :street1, :street2, :city, :state, :zip
has_many :contacts
end
Run Code Online (Sandbox Code Playgroud)
我想在创建新联系人时,访问属于公司其他联系人的所有地址.以下是我代表公司的方式:
class Company < ActiveRecord::Base
attr_accessible :name, :phone, :addresses
has_many :contacts
has_many :addresses, :through => :contacts
end
Run Code Online (Sandbox Code Playgroud)
以下是我在View for _form for Contact中创建字段的方法,以便当有人创建新的Contact时,他们将地址传递给Address模型并将该地址与Contact联系起来:
<% f.fields_for :address, @contact.address do |builder| %>
<p>
<%= builder.label :street1, "Street 1" %> </br>
<%= builder.text_field :street1 %>
<p>
<% end %>
Run Code Online (Sandbox Code Playgroud)
当我尝试编辑时,Street 1的字段为空白.我不知道如何显示show.html.erb中的值.
在底部是我的错误控制台 - 似乎无法在地址表中创建值:
我的联系人控制器如下:
def new
@contact = Contact.new
@contact.address.build # Iundefined method `build' for nil:NilClass
@contact.date_entered = Date.today
@campaigns = Campaign.find(:all, :order => "name")
if params[:campaign_id].blank?
else
@campaign = Campaign.find(params[:campaign_id])
@contact.campaign_id = @campaign.id
end
if params[:company_id].blank?
else
@company = Company.find(params[:company_id])
@contact.company_name = @company.name
end
end
def create
@contact = Contact.new(params[:contact])
if @contact.save
flash[:notice] = "Successfully created contact."
redirect_to @contact
else
render :action => 'new'
end
end
def edit
@contact = Contact.find(params[:id])
@campaigns = Campaign.find(:all, :order => "name")
end
Run Code Online (Sandbox Code Playgroud)
这是我的错误控制台的片段: 我正在POST属性,但它不是在地址表中创建....
处理ContactsController #create(适用于2010-05-12 21:16:17的127.0.0.1)
[POST]参数:{"commit"=>"提交","authenticity_token"=>"d8/gx0zy0Vgg6ghfcbAYL0YtGjYIUC2b1aG + dDKjuSs =","contact"=> {"company_name"=>"Allyforce","title"=>" ","campaign_id"=>"2","address_attributes"=> {"street1"=>"abc"},"fax"=>"","phone"=>"","last_name"=>"" ,"date_entered"=>"2010-05-12","email"=>"","first_name"=>"abc"}}
公司负荷(0.0ms)[0m [0mSELECT*FROM"公司"WHERE("公司"."名称"='Allyforce')LIMIT 1 [0m
地址创建(16.0ms)[0m
[0; 1mINSERT INTO"地址"("city","zip","created_at","street1","updated_at","street2","state")VALUES(NULL,NULL ,'2010-05-13 04:16:18',NULL,'2010-05-13 04:16:18',NULL,NULL)[0m联系创建(0.0ms)[0m
[0mINSERT INTO"contacts"("company","created_at","title","updated_at","campaign_id","address_id","last_name","phone","fax") ,"company_id","date_entered","first_name","email")VALUES(NULL,'2010-05-13 04:16:18','','2010-05-13 04:16:18', 2,2,'','','',5,'2010-05-12','abc','')[0m
只是一个老生常谈的问题,如果您在联系表单中使用此内容不应该以单数形式表示?
<% f.fields_for :address, @contact.address do |builder| %>
<p>
<%= builder.label :street1, "Street 1" %> </br>
<%= builder.text_field :street1 %>
<p>
<% end %>
Run Code Online (Sandbox Code Playgroud)
在你的行动中你还必须做
@ycontact.build_address
Run Code Online (Sandbox Code Playgroud)
如果您查看源代码,您的输入字段应该如下所示。
<输入类型=“文本”大小=“30”名称=“联系人[地址属性][street1]”id=“联系人地址属性_street1”>
我认为你的关联也有问题,如果你将 address_id 存储在 contact 中,那么
class Contact < ActiveRecord::Base
belongs_to :address
accepts_nested_attributes_for :address
end
class Address < ActiveRecord::Base
attr_accessible :street1
has_many :contacts
end
Run Code Online (Sandbox Code Playgroud)
我认为这就是您的情况,因为您想将一个地址分配给多个联系人。
如果您将 contact_id 存储在地址模型中,您也可以进行相反的操作:
class Contact < ActiveRecord::Base
has_one :address
accepts_nested_attributes_for :address
end
class Address < ActiveRecord::Base
attr_accessible :street1
belongs_to :contact
end
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您不能拥有具有相同地址的用户。
更新
在您的用户 show.html.eb 中您可以使用
<%= @contact.address.street1 %>
Run Code Online (Sandbox Code Playgroud)
在您公司的 show.html.erb 中,您可以显示如下地址:
<% @company.addresses.each do |address| %>
<%= address.street1 %>
...
<% end %>
Run Code Online (Sandbox Code Playgroud)
在您的用户编辑页面上,表单字段应与 new.html.erb 中的表单字段相同,只是表单标记应如下所示:
<% form_for @contact do |form| %>
<%=render :partial=>'fields' %>
<% end %>
Run Code Online (Sandbox Code Playgroud)
部分字段包含您的所有字段:
<% f.fields_for :address, @contact.address do |builder| %>
<p>
<%= builder.label :street1, "Street 1" %> </br>
<%= builder.text_field :street1 %>
<p>
<% end %>
Run Code Online (Sandbox Code Playgroud)
这应该有效。
更新2
您可以通过以下方式访问属于某个公司的所有地址:
@company.addresses
Run Code Online (Sandbox Code Playgroud)
如果你有
class Company<Activerecord::Base
has_many :contacts
has_many :addresses, :through=>:contacts
end
Run Code Online (Sandbox Code Playgroud)
关于草稿或默认地址。您可以根据您的需要有不同的选择。我希望联系人可以从数据库中选择现有地址之一。您可以在联系表单中选择一个选择框,例如:
<%= form.select :address_id, options_from_collection_for_select(@company.addresses, 'id', 'street1')%>
Run Code Online (Sandbox Code Playgroud)
您还可以使用一些奇特的 JavaScript 来添加或删除地址表单,在这种情况下,如果用户选择现有地址之一。在这种情况下,您必须从表单中删除 address_attributes。我建议使用 javascript 代码创建一个链接,以添加和删除(切换样式)address_attributes。
| 归档时间: |
|
| 查看次数: |
3777 次 |
| 最近记录: |