创建新记录时保存belongs_to数据

时间:2011-12-12 04:28:18

标签: ruby-on-rails ruby-on-rails-3.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,或输入新的params[:party][:hostess_id]。 (这是通过jQuery自动完成来查找现有记录的。)如果选择了现有记录,params[:party][:hostess_id]将具有正确的值。否则,0params[:party][:hostess]Hostess包含用于创建新params[:party][:hostess][:first_name]的数据(例如,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,因此无法创建新的{{1}})。有什么建议吗?

1 个答案:

答案 0 :(得分:4)

根据您提供的模型,您可以使用一些导轨工具(例如inverse_ofaccepts_nested_attributes_forattr_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]传递给派对模型并让它为您构建女主人。

第三,我们为attr_accessor设置:hostess_id,它可以清理控制器逻辑,允许模型决定接收hostess对象或hostess_id值。

第四,我们确保用现有的女主人覆盖hostess,以防我们获得正确的hostess_id值。我们通过在before_validation回调中分配女主人来做到这一点。

我实际上并未检查此代码是否有效,但希望它能够揭示足够的信息来解决您的问题并公开更多有用的工具潜伏在rails中。