2012-06-06 78 views
1

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的服务器输出请注意:我是很新的轨道,以便用裸我在这里。此外,我已经通过论坛寻找所有问题的答案。我发现了一些类似的东西,但是当我测试它们时,它们都没有工作。

最后,在查看模型后,您可能会想知道电子​​邮件/登录信息的来源。它们是在我们系统的模型中构建的,但不是这个问题的一部分,所以我省略了代码。他们在工作,所以问题不在这一边。

无论如何,感谢您的时间,请让我知道如果您需要更多的信息。

回答

0

检查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 
+0

我能看到你与上面的代码段去。我稍微修改了它(以几种不同的方式)。我可以让它无误地执行,但别名永远不会被更新。我认为上面的例子很接近,但并不完全。 – creeves

+0

也许你需要保存它? (team_mate.save) –

+0

@ user.save实际上是在代码执行后立即调用的,所以它已经在那里。出于谨慎的考虑,我用team.save试了一下,但它仍然无法工作。 (我知道你说'team_mate.save,但我测试的代码与你所建议的代码略有不同 - 同样的概念,但我先进入team_mates,因为团队是team_mates的嵌套属性) – creeves