2013-04-20 23 views
0

我有用戶,用戶有很多客戶端和聯繫人。客戶也有很多聯繫人(聯繫人屬於用戶和客戶)。嵌套表格無法保存client_id和user_id

在我的客戶端視圖中,我想創建一個新的客戶端,並在同一個表單上允許用戶爲該客戶端創建第一個聯繫人。最初,我認爲使用嵌套屬性可以做到這一點,但我遇到了一些問題。當我在clients_controller#create中保存@client時,我無法保存,因爲user_id不能爲空,並且client_id不能爲聯繫人爲空。這是我到目前爲止有:

客戶控制指標(如新的客戶端窗體位於):

def index 
    @clients = current_user.clients 
    @client = Client.new 
    @contact = @client.contacts.build 

    respond_to do |format| 
     format.html # index.html.erb 
     format.json { render json: @clients } 
    end 
    end 

和創建方法:

def create 
    @client = current_user.clients.new(params[:client]) 

    respond_to do |format| 
     if @client.save 

和形式:

= form_for(@client) do |f| 
      = f.fields_for(:contacts) do |contact| 

但是,當我去保存它需要一個client_id和user_id ...但我不能真正設置使用嵌套的a ttributes。我怎麼能做到這一點?有沒有更好的方法來做到這一點?這裏是我的PARAMS:

{"name"=>"asdf", "contacts_attributes"=>{"0"=>{"name"=>"asdf", "email"=>"[email protected]"}}} 

我只是嘗試添加缺少的值直接進入contacts_attributes但由於@client尚未保存的是,我不能指定client.id聯繫:

params[:client][:contacts_attributes]["0"].merge!(:user_id => current_user.id) 
params[:client][:contacts_attributes]["0"].merge!(:client_id => @client.id) 

即使設置了user_id,它仍然表示用戶缺失。

回答

0

Did you add accepts_nested_attributes_for to your model?你需要的東西是這樣的:

class Client < ActiveRecord::Base 
    has_many :contacts 
    accepts_nested_attributes_for :contacts 
end 

此外,你應該在你創建操作使用build

@client = current_user.clients.build(params[:client]) 
0

這裏是我的設置,對於您的示例工作:

app/models/user.rb

class User < ActiveRecord::Base 
    attr_accessible :name, :clients_attributes 

    has_many :clients 

    accepts_nested_attributes_for :clients 
end 

app/models/client.rb

class Client < ActiveRecord::Base 
    attr_accessible :company, :contacts_attributes 

    belongs_to :user 
    has_many :contacts 

    accepts_nested_attributes_for :contacts 
end 

app/models/contact.rb

class Contact < ActiveRecord::Base 
    attr_accessible :email 

    belongs_to :client 
end 

app/controllers/users_controller.rb

class UsersController < ApplicationController 
    # ... 

    def new 
    @user = User.new 
    @client = @user.clients.build 
    @concact = @client.contacts.build 

    respond_to do |format| 
     format.html # new.html.erb 
     format.json { render json: @user } 
    end 
    end 

    # ... 
end 

的實際形式:

<% # app/views/users/new.erb %> 

<%= form_for(@user) do |f| %> 
    <div class="field"> 
    <%= f.label :name %><br /> 
    <%= f.text_field :name %> 
    </div> 

    <div class="field"> 
    <%= f.fields_for :clients do |client_form| %> 
     <h5>Client</h5> 
     <%= client_form.label :company, "Company name" %> 
     <%= client_form.text_field :company %> 

     <div class="field"> 
     <h5>Contact</h5> 
     <%= client_form.fields_for :contacts do |contact_form| %> 
      <%= contact_form.label :email %> 
      <%= contact_form.text_field :email %> 
     <% end %> 
     </div> 
    <% end %> 
    </div> 

    <div class="actions"> 
    <%= f.submit %> 
    </div> 
<% end %> 

的形式如下:

enter image description here

這裏是如何PARAMS的形式發送的樣子:

{ 
    "utf8"=>"✓", 
    "authenticity_token" => "bG6Lv62ekvK7OS86Hg/RMQe9S0sUw0iB4PCiYnsnsE8=", 
    "user" => { 
    "name" => "My new user", 
    "clients_attributes" => { 
     "0" => { 
     "company" => "Client's Company Name LLC", 
     "contacts_attributes" => { 
      "0" => { 
      "email" => "[email protected]" 
      } 
     } 
     } 
    } 
    }, 
    "commit" => "Create User" 
} 

更新

以允許添加更多的公司/聯繫人之後,改變UsersController#edit行動在:

class UsersController < ApplicationController 
    # ... 

    def edit 
    @client = current_user.clients.build 
    @concact = @client.contacts.build 

    respond_to do |format| 
     format.html # new.html.erb 
     format.json { render json: @user } 
    end 
    end 

    # ... 
end 
+0

如果我不想通過用戶模型執行此操作,該怎麼辦?我不是每次都創建一個新用戶......只有一個新的客戶和聯繫人。 – 2013-04-20 19:31:06

+0

馬修,我已經更新了答案。這是否有用? – gmile 2013-04-20 19:40:51

+0

嗯..通過@user模型絕對必要嗎?這對我來說似乎是錯誤的,因爲聯繫與客戶關係更密切(我認爲?)。有沒有用戶的方式?特別是因爲視圖和路線現在都在客戶端。 – 2013-04-21 00:51:22

0

以下驗證s可能會導致這個問題,因爲在驗證運行時,父id沒有被分配給子對象。解決方法是刪除這些驗證或將它們設置爲僅在更新時運行。這樣你就失去了這些創建方法的驗證,但它的工作原理。

# client.rb 
validates :user, presence: true 

# contact.rb 
validates :client, presence: true