2011-08-24 36 views
0

我有一個處理成員和地址問題域的數據模型的多對多關係設置。基本上,一個'會員'可以有多個'地址',就像你有工作地址和家庭住址一樣。在多對多關係中加入表屬性更新

我想在連接表上存儲其他屬性並保存除外鍵屬性以外的數據。網絡上有很多關於多對多關係的例子,但是我沒有找到關於存儲額外數據的細節/例子。

這是我堅持的問題。

的模型設置爲:

模式

class Member < ActiveRecord::Base 
    has_many :member_addresses 
    has_many :addresses, :through => :member_addresses 
end 

class MemberAddress < ActiveRecord::Base 
    belongs_to :address # foreign key for address -> address_id 
    belongs_to :member # foreign key for member ->member_id 
end 

class Address < ActiveRecord::Base 
    has_many :member_addresses 
    has_many :members, :through => :member_addresses 

    accepts_nested_attributes_for :members, :allow_destroy => true 
end 

的 'accepts_nested_attributes' 的地址類是嵌套形式。

數據庫架構/遷移 的表(簡化爲張貼)​​是在連接表定義爲

create_table "addresses", :force => true do |t| 
    t.string "firstline" 
    t.string "state" 
    .... 
end 

create_table "member", :force => true do |t| 
    t.string "name" 
    .... 
end 

create_table "member_addresses", :force => true do |t| 
    t.integer "member_id" 
    t.integer "address_id" 
    t.string "address_type" 
end 

字段「address_type」被用於標記,其與相關聯的地址的類型該成員(又名;「家」或「工作」)

它正在更新此字段,我卡住了。

控制器&查看

的member_controller設置的模式,如:

members_controller.rb 
def new 
    @member = Member.new 
    @member.addresses.build #pre-build the associated address 
end 

然後爲會員頁面視圖行動

<%=的form_for @成員do | m | %>

<%= m.label :first_name, "First Name"%> 
    <%= m.text_field :first_name %> 
    </p> 

    <%= m.fields_for :addresses do |addrform|%> 
    <%= addrform.label :firstline %> 
    <%= addrform.text_field :firstline %> 
    <% end %> 

    <br /> 
    <%= label_tag 'Type of address' %> 
    <%= text_field_tag 'addrtype' %> 
    <br /> 
    <%= m.submit "Add" %><br /> 

<%結束%>

的想法是,與上會員模式「accepts_nested_attributes」我可以進入表單上的數據在名稱和地址屬性添加。附加label_tag是被張貼了,我想存儲

所以當形式在後的數據被填充(形成陷阱)地址類型數據的模樣:

{"utf8"=>"âœ「", 
    "authenticity_token"=>"E0R038rcdJmBGjjxQ9nQLHGVbzM4ejA0vsEaIvqkwkE=", 
    "member"=>{"first_name"=>"James", 
    "last_name"=>"SMith", 
    "addresses_attributes"=>{"0"=>{"firstline"=>"this is the first line"}}}, 
    "addrtype"=>"home", 
    "commit"=>"Add"} 

所有優秀的 - 我得到我會員數據和地址數據,以及附加字段「ADDRTYPE」,這是用於承載我的附加數據

現在如何獲取數據到relati在或加入表格?在member_controller創建行動

def create 
    # create a member with the params posted 
    @member = Member.new(params[:member]) 

    # get data for 'relation data' 
    @addr_type = params[:addrtype] 



    if @member.save! 
     #update the relation now created with the address type 
     @member.member_addresses.first.address_type = @addr_type 

     # save the relationship (is this necessary?) 
     @member.save! 

     redirect_to members_path 
    end 

正如你可以在看到創建我試圖填補數據上的連接表,然後強制再次保存,這樣的關係或協會與附加屬性被保存。

這不起作用,和/或我做錯了。

任何建議將不勝感激。

回答

1

嘗試改變你的模型,如下所示:

class Member < ActiveRecord::Base 
    has_many :member_addresses 
    accepts_nested_attributes_for :member_addresses, :allow_destroy => true 
end 

class MemberAddress < ActiveRecord::Base 
    belongs_to :member  
    has_many :addresses 
    accepts_nested_attributes_for :addresses, allow_destroy => true 
end 

class Address < ActiveRecord::Base 
    belongs_to :member_addresses 
end 

,改變你的member_controller.create方法

@member = Member.new(params[:member]) 

這應該允許您通過MemberController.create方法創建MemberAddresses和地址。

這2個RailsCasts也可能是值得一看

#196 Nested Model Form Part 1
#197 Nested Model Form Part 2

0

還不如精通Rails的,我想是,但研究表明,可能這可能工作:

而不是

@member.member_addresses.first.address_type = @addr_type

嘗試

@member.member_addresses.create(:address_type => @addr_type)

+0

正確的 - 它的工作原理提供了@member保存第一否則你得到的ActiveRecord :: RecordNotSaved:您不能調用創建,除非parent保存 –

+0

唯一的問題是,如果有一個@ member.save!,必須保存父項,那麼在MemberAddresses連接表中創建的兩個記錄中會創建額外的「創建」結果;一個用於第一次保存,它具有兩個外鍵,一個用於具有address_type字段和成員對象的ID的「創建」。它缺少address_id字段 –