2012-06-06 119 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