2011-10-10 17 views
0

3つのネストされたモデルを一度に作成しようとしていて、検証に問題があります。ネストされたモデルの作成 - Rails 3.1

は、これらの私のモデルです:

class UserEntity < ActiveRecord::Base 
    has_many :users,   :dependent => :restrict, :autosave => true 
end 

class User < ActiveRecord::Base 
    has_many :user_login_services, :dependent => :destroy, :autosave => true 
    belongs_to :user_entity 
end 

class UserLoginService < ActiveRecord::Base 
    belongs_to :user 
    #validates :user_id, :presence => true 
end 

(UserEntity多くのユーザーを持つ企業、可能UserLoginServiceは、などのFacebook、OpenIDの、などOmniauthサービスに使用される。)

ユーザーが使用して作成されています

def new_user_login(tokens) 
    user_entity = UserEntity.new 
    user = user_entity.users.build(:email => tokens[:email], :password => Devise.friendly_token[0,20], :first_name => tokens[:first_name], :last_name => tokens[:last_name], :has_local_password => false) 
    user.skip_confirmation! 
    user.user_login_services.build(:provider => tokens[:provider], :uid => tokens[:uid], :uname => tokens[:name], :uemail => tokens[:email])  
    user_entity.save! 
    user.confirm! 

このコードは正常に動作しているようで、3つのテーブルすべてに適切なエントリを作成します。コードは、検証せずに正常に動作しているようだ、とuser_login_servicesテーブル内のuser_idであることを私に

ActiveRecord::RecordInvalid (Validation failed: Users user login services user can't be blank): 
    app/controllers/users/omniauth_callbacks_controller.rb:86:in `new_user_login' 

を取得UserLoginService、中注私は「:user_idは、存在=>真を検証する」アンコメントすると、問題が発生します適切な値に設定します。

なぜこのエラーが発生しますか?これをどのように解決しますか?

答えて

1

accepts_nested_attributes_forinverse_ofの関係を定義する必要があります。

class UserEntity < ActiveRecord::Base 
    has_many :users, :dependent => :restrict, :autosave => true, :inverse_of => :users_entity 
    accepts_nested_attributes_for :users 
end 

class User < ActiveRecord::Base 
    has_many :user_login_services, :dependent => :destroy, :autosave => true, :inverse_of => :user 
    belongs_to :user_entity, :inverse_of => :users 
    accepts_nested_attributes_for :user_login_services 
end 

class UserLoginService < ActiveRecord::Base 
    belongs_to :user, :inverse_of => :users_login_services 
    validates :user, :presence => true 
end 

は、私はまた、あなたが関連付けられている userの存在を検証したいと UserLoginServiceuser_idを持っていないだけであると仮定 validates :uservalidates :user_idを切り替えます。一言で言えば

+0

ありがとう、inverse_ofを指定してくれてありがとうございました!そうでなければ、Railsは保存したときにネストされたモデルを最初に保存しようとします(ネストされたモデルはbelongs_toのトップモデルになります)。これはトップモデルがまだ作成されていないため失敗します。 – astgtciv

1

あなたのモデルで

class UserEntity < ActiveRecord::Base 
    has_many :users 
    accepts_nested_attributes_for :users 
end 

class User < ActiveRecord::Base 
    belongs_to :user_entity 
    has_many :user_login_services, :dependent => :destroy 
    accepts_nested_attributes_for :user_login_services 
end 

class UserLoginService < ActiveRecord::Base 
    belongs_to :user 
    validates :user_id, :presence => true 
end 
あなたのコントローラで

def create 
    @user_entity = UserEntity.new(params[:user_entity]) 
    @user_entity.save 
    # To Do: handle redirections on error and success 
end 

とフォームで

<%= form_for(@user_entity) do |f| %> 
    <%= f.fields_for :users do |u| %> 
    <%= u.fields_for :user_login_services do |ul| %> 
     <%= ul.select :user_id, @user_entity.users.collect{|u| [u.name, u.id]} %> 
    <% end %> 
    <% end %> 
<% end %> 

さらに私はあなたがチェックアウトをお勧めします: http://railscasts.com/episodes/196-nested-model-form-part-1

関連する問題