创建嵌套模型 - Rails 3.1

时间:2011-10-10 15:41:28

标签: model ruby-on-rails-3.1

我试图一次创建3个嵌套模型,但我的验证有问题。

这些是我的模特:

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用于Omniauth服务,如Facebook,openID等。)

使用

创建用户
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个表中创建适当的条目。当我取消注释'validates:user_id,:presence =&gt;时会出现问题。在UserLoginService中为true,它让我

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'

请注意,如果没有验证,代码似乎工作正常,并且user_login_services表中的user_id被设置为正确的值。

为什么我会收到此错误,我该如何解决?

2 个答案:

答案 0 :(得分:2)

简而言之:

在你的模特中

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

答案 1 :(得分: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

我还将validates :user_id切换为validates :user,假设您要验证相关user的存在,而不只是UserLoginServiceuser_id