Rails - 保存到数据库之前更新嵌套属性
Stackoverflow的长时间阅读器,但从未发现自己有能力提出问题(尚未得到解答)。我想有一个第一次为一切,所以这里有云......Rails - 保存到数据库之前更新嵌套属性
系统信息:
的Ruby版本= 1.8.7
的Rails版本3.2.2 =
现状:
我们有一个用户注册系统的应用程序。为了正确连接并填充所有表格,我们正在注册视图中使用复杂/嵌套表格。实际上我的嵌套表单工作得很完美,所有东西都应该被填充,真的很棒。
这是问题:我需要设置一个嵌套属性的值之一后的表单发布,但保存记录之前。
下面是一个简单的例子,所以你可以看到我在说些什么好一点: 用户在我们的网站注册。在用户数据表中创建记录时创建。每个用户也被分类为team_mate(连接表)并分配给他们自己的个人团队(起初)。但是,一个“团队”(表)也有一个“别名”字段,在用户创建时我们希望设置用户的名字(不必让他们的名字输入“别名“字段)。
所以,我想这个问题将是:如何手动设置嵌入属性的值在表单后和记录保存到数据库之前?
甲表模式的(简化的)实施例看起来如下:
用户(ID,名字,姓氏,created_at,的updated_at)
Team_mates(ID,USER_ID,TEAM_ID,created_at,的updated_at ) - 连接表
队(ID,别名,created_at,的updated_at)
型号:
User.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
Team.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
控制器
Users_controller.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
查看
new.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'
而在成形后的
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"=>"[email protected]"}}, "login_attributes"=>{"user_login"=>"lkjsdfooiusfd", "password_encrypted"=>"[FILTERED]"}}, "utf8"=>"✓", "commit"=>"Create User", "authenticity_token"=>"CQLQ93/0VlncSzMlmtLPHgaVrrvjuHFN+lN6CYCsiR8="}
终于
Rails的服务器输出请注意:我是很新的轨道,以便用裸我在这里。此外,我已经通过论坛寻找所有问题的答案。我发现了一些类似的东西,但是当我测试它们时,它们都没有工作。
最后,在查看模型后,您可能会想知道电子邮件/登录信息的来源。它们是在我们系统的模型中构建的,但不是这个问题的一部分,所以我省略了代码。他们在工作,所以问题不在这一边。
无论如何,感谢您的时间,请让我知道如果您需要更多的信息。
检查http://archives.ryandaigle.com/articles/2009/2/1/what-s-new-in-edge-rails-nested-attributes
为了支持新对象的同时创建和 现有的编辑,我们必须使用哈希的数组,一个一对多 协会或单一个散列一对一的联系。如果否:id 属性存在,则假定它代表嵌套模型 创建。
不是100%肯定..我没用过\之前测试过,但是这应该给你一个想法
@user.teams.each do |team|
team.team_mates do |team_mate|
# To edit existing
team_mate.team_attributes = [ { :id => team.id, :alias => @user.first_name } ]
# To create new
team_mate.team_attributes = [ { :alias => @user.first_name } ]
team_mate.save
end
end
我能看到你与上面的代码段去。我稍微修改了它(以几种不同的方式)。我可以让它无误地执行,但别名永远不会被更新。我认为上面的例子很接近,但并不完全。 – creeves
也许你需要保存它? (team_mate.save) –
@ user.save实际上是在代码执行后立即调用的,所以它已经在那里。出于谨慎的考虑,我用team.save试了一下,但它仍然无法工作。 (我知道你说'team_mate.save,但我测试的代码与你所建议的代码略有不同 - 同样的概念,但我先进入team_mates,因为团队是team_mates的嵌套属性) – creeves