在Rails表单提交中分离多个模型

时间:2011-12-16 15:39:06

标签: ruby-on-rails ruby-on-rails-3 params

具体来说,我有一个用于创建User的表单。其中一个字段是Group,这是一个单独的模型。在User#create操作期间,我致电Group.find_or_create_by_name以检查Group是否已存在,方法是拉出params[:user][:group],如果不Group则创建User存在。

但是,当我创建params[:user]时,我无法通过params[:user][:group],因为String不是一个群组,而是params[:user]。如果我可以将params[:group]@group = Group.find_or_create_by_name(params[:user][:group]) @group.save! @user = @group.users.build(params[:user]) 提供给我的控制器,而不是捆绑在单个变量下的所有内容,那将会容易得多,但我不知道该怎么做。

相关代码:

用户#创建

create_table "users", :force => true do |t|
  t.string   "name",                :default => "",    :null => false
  t.string   "email",                                  :null => false
  t.integer  "group_id"

部分用户架构

create_table "groups", :force => true do |t|
  t.string   "name"
  t.text     "description"
  t.datetime "created_at"
  t.datetime "updated_at"

部分群组架构

{"commit"=>"Register",
 "authenticity_token"=>"x1KgPdpJop5H2NldsPtk0+mBDtrmpM/oNABOxjpabIU=",
  "utf8"=>"✓",
  "user"=>{"name"=>"aName",
  "group"=>"aGroupName",
  "password_confirmation"=>"[FILTERED]",
  "password"=>"[FILTERED]",
  "email"=>"anEmail"}}

表格提交中的参数转储

params

我遇到的最佳解释是this问题。

我真的不想重新开始重新安排我的控制器里面的{{1}},因为这真让我感到不安,而且看起来很糟糕。这让我怀疑自己是否遇到了更大的问题。

如果违反Rails惯例,那么最好的方法是什么,为什么不这样做呢?

2 个答案:

答案 0 :(得分:0)

我认为在这里执行此操作的正确方法是将用户从群组中构建出来。如果您处于GroupsController的操作中,例如,将新用户添加到组中,那将是合适的。我认为这里最好的方法是做到以下几点:

@group = Group.find_or_create_by_name(params[:user][:group])
@group.save!
@user = User.new(params[:user])
@user.group_id = @group.id
@user.save

由于您处于UsersController的新操作中,因此创建新用户而不是将其构建为关联,然后将该用户添加到已存在或已存在的组中似乎更合适刚刚创建。

这有意义吗?

答案 1 :(得分:0)

所以,我要拼出我学到的所有内容,以防其他人像我一样理解这一点。另外,如果我在这里弄错了,请纠正我。

如果您正在使用一次创建多个模型实例的表单(最好是相关的模型实例),则首先需要在模型定义中使用帮助器accepts_nested_attributes_for(可能在您声明的关联下面)。这样做的原因是它创建了一个知道如何编写该类关联模型的setter方法。 (注意:您也可以在主模型中自己定义此方法)。完成后,您可以在fields_for内嵌套form_for,Rails将知道如何进行正确的分配。

我最初认为accepts_nested_attributes_for指的是嵌套资源,但绝对不是这样。如果您正在寻找更多信息,请参阅The Rails 3 Way的第11.8.3节(第343-347页)。