2011-12-12 45 views
1
class Party < ActiveRecord::Base 
    belongs_to :hostess, class_name: 'Person', foreign_key: 'hostess_id' 
    validates_presence_of :hostess 
end 

class Person < ActiveRecord::Base 
    has_many :parties, foreign_key: :hostess_id 
end 

當在創建新Party,視圖允許用戶選擇現有Hostess,或者輸入一個新的。 (這是通過jQuery自動完成來查找現有記錄完成的。)如果選擇了現有記錄,則params[:party][:hostess_id]將具有正確的值。否則,params[:party][:hostess_id]0params[:party][:hostess]具有創建新的Hostess(例如,params[:party][:hostess][:first_name]等)保存belongs_to的數據創建新的記錄

Parties控制器的數據:

def create 
    if params[:party][:hostess_id] == 0 
    # create new hostess record 
    if @hostess = Person.create!(params[:party][:hostess]) 
     params[:party][:hostess_id] = @hostess.id 
    end 
    end 
    @party = Party.new(params[:party]) 
    if @party.save 
    redirect_to @party, :notice => "Successfully created party." 
    else 
    @hostess = @party.build_hostess(params[:party][:hostess]) 
    render :action => 'new' 
    end 
end 

這當我通過在現有Hostess工作正常,但在嘗試創建新的Hostess(無法創建新的Hostess/Person,因此無法創建新的Party)時它不起作用。有什麼建議麼?

回答

4

鑑於您提供的型號,您可以使用幾種導軌工具(如inverse_of,accepts_nested_attributes_for,attr_accessor和回調)以更簡潔的方式進行此設置。

# Model 
class Party < ActiveRecord::Base 
    belongs_to :hostess, class_name: 'Person', foreign_key: 'hostess_id', inverse_of: :parties 
    validates_presence_of :hostess 

    # Use f.fields_for :hostess in your form 
    accepts_nested_attributes_for :hostess 

    attr_accessor :hostess_id 

    before_validation :set_selected_hostess 

    private 
    def set_selected_hostess 
    if hostess_id && hostess_id != '0' 
     self.hostess = Hostess.find(hostess_id) 
    end 
    end 
end 

# Controller 
def create 
    @party = Party.new(params[:party]) 

    if @party.save 
    redirect_to @party, :notice => "Successfully created party." 
    else 
    render :action => 'new' 
    end 
end 

我們在這裏做了很多事情。

首先,我們使用inverse_of中的belongs_to關聯,它允許您使用validate presence of the parent model

其次,我們使用accepts_nested_attributes_for,它允許您將params[:party][:hostess]傳入派對模型,讓它爲您搭建女主人。

第三,我們正在爲:hostess_id設立attr_accessor,其中清理控制器邏輯頗有幾分,使模型決定做什麼它是否作爲hostess對象或hostess_id值。第四,如果我們有適當的hostess_id值,我們確保覆蓋hostess與現有的女主人。我們通過在before_validation回調中分配女主人來做到這一點。

我沒有真正檢查這段代碼的工作原理,但希望它揭示了足夠的信息來解決你的問題,並揭露了更多有用的工具,潛伏在rails中。

+0

非常感謝您提供瞭如此全面的答案。只有'def set_selected_hostess'需要使用Person模型,例如'self.hostess = Person.find(hostess_id)'。我在模型中也有attr_accessible,我註釋了。無論如何不需要(由發電機添加)。 – Brenda

+0

你搖滾!非常感謝你!!!但是我在Rails 4中遇到了問題。我有:一個人有很多票。在票據表格中,我需要填寫個人屬性。當我執行@ticket = Ticket.new(ticket_params)時,我得到ID = 1的票未找到ID = 1的票,ID = – fabricioflores

相關問題