Stackoverflow 的长期读者,但从未发现自己能够提出问题(尚未回答)。我想每件事都有第一次,所以就这样吧……
系统信息:
Ruby 版本 = 1.8.7
Rails 版本 = 3.2.2
情况:
我们有一个带有用户注册系统的应用程序。为了正确连接和填充我们所有的表格,我们在注册视图中使用复杂/嵌套表格。实际上,我的嵌套表单工作得很好,一切都按照它应该的方式填充,真的很棒。
这是问题所在:我需要在表单发布之后但在保存记录之前设置嵌套属性之一的值之一。
这是一个简单的示例,因此您可以更好地了解我在说什么:用户在我们的网站上注册。当他们注册时,会在用户数据表中创建一条记录。每个用户也被归类为一个 team_mate(加入表)并分配给他们自己的团队(起初)。但是,“团队”(表)中也有一个“别名”字段,在初始创建用户时,我们希望将其设置为用户的名字(无需让他们将名字输入到“表单上的别名字段)。
所以,我想问题是: 如何在表单发布之后和记录保存到数据库之前手动设置嵌套属性的值?
表模式的一个(简单)示例如下所示:
用户(id、first_name、last_name、created_at、updated_at)
Team_mates(id, user_id, team_id, created_at, updated_at) - 加入表
团队(id、别名、created_at、updated_at)
楷模:
用户.rb
class User < ActiveRecord::Base
has_many :team_mates, :dependent => :destroy
has_many :teams, :through => :team_mates, :foreign_key => :team_id
accepts_nested_attributes_for :team_mates, :allow_destroy => true
before_save :set_defaults
private
def set_defaults
#want to set :users => :team_mates_attributes => :team_attributes => :alias to @user.first_name here
# Would prefer to handle this here instead of in the controller.
end
end
团队.rb
class Team < ActiveRecord::Base
has_many :team_mates, :dependent => :destroy
has_many :users, :through => :team_mates, :foreign_key => :user_id
end
Team_mate.rb
class TeamMate < ActiveRecord::Base
belongs_to :user
belongs_to :team
accepts_nested_attributes_for :team, :allow_destroy => true
end
控制器
用户控制器.rb
class UsersController < ApplicationController
def new
@user = User.new
@user.emails.build(:is_default_email => 1)
@user.build_login
@user.team_mates.build.build_team(:alias => 'Clinton444', :created_at => Time.new, :updated_at => Time.new)
respond_to do |format|
format.html
format.json { render :json => @match }
end
end
def create
@user = User.new(params[:user])
@user.attributes = ({ "user" => { "team_mates" => { "team" => { "alias" => @user.first_name } } } }) #--this doesn't work...
@user.attributes = ({ :user => { :team_mates => { :team => { :alias => @user.first_name } } } }) #--neither does this...
respond_to do |format|
if @user.save
format.html { redirect_to(@user, :notice => 'User was successfully created.') }
format.json { render :json => @user, :status => :created, :location => @user }
else
format.html { render :action => "new" }
format.json { render :json => @user.errors, :status => :unprocessable_entity }
end
end
end
看法
新的.html.haml
= form_for(@user, :html => {:class => 'form-horizontal'}) do |f|
- if @user.errors.any?
.alert
%h2
= pluralize(@user.errors.count, "error")
prohibited this post from being saved:
%ul
- @user.errors.full_messages.each do |msg|
%li
= msg
%fieldset
.control-group
= f.label :first_name, :class => "control-label"
.controls
=f.text_field :first_name, :class => "span8"
.control-group
= f.label :last_name, :class => "control-label"
.controls
=f.text_field :last_name, :class => "span8"
= f.fields_for :emails do |e|
=e.hidden_field :is_default_email, :class => "span8"
.control-group
= e.label :email, :class => "control-label"
.controls
=e.text_field :email, :class => "span8"
= f.fields_for :team_mates do |tm|
= tm.fields_for :team do |t|
=t.hidden_field :alias, :class => "span8"
=t.hidden_field :created_at, :class => "span8"
=t.hidden_field :updated_at, :class => "span8"
= f.fields_for :login do |e|
.control-group
= e.label :user_login, :class => "control-label"
.controls
=e.text_field :user_login, :class => "span8"
.control-group
= e.label :password_encrypted, :class => "control-label"
.controls
=e.text_field :password_encrypted, :class => "span8"
.control-group
.controls
=f.submit :class => 'btn btn-primary btn-medium'
最后
表单发布上的 Rails 服务器输出
Parameters: {"user"=>{"team_mates_attributes"=>{"0"=>{"team_attributes"=>{"created_at"=>"Wed Jun 06 09:52:19 -0600 2012", "alias"=>"asfs444", "updated_at"=>"Wed Jun 06 09:52:19 -0600 2012"}}}, "first_name"=>"lkjlkjlsdfslkjeowir", "last_name"=>"ouisodifuoixv", "emails_attributes"=>{"0"=>{"is_default_email"=>"1", "email"=>"lpisfsopf@psflsjdk.com"}}, "login_attributes"=>{"user_login"=>"lkjsdfooiusfd", "password_encrypted"=>"[FILTERED]"}}, "utf8"=>"✓", "commit"=>"Create User", "authenticity_token"=>"CQLQ93/0VlncSzMlmtLPHgaVrrvjuHFN+lN6CYCsiR8="}
查看模型后,您可能想知道电子邮件/登录的来源。它们是在我们系统的模型中构建的,但实际上并不是这个问题的一部分,所以我省略了它们的代码。他们正在工作,所以问题不在那边。