2012-01-30 62 views
2

我试图创建使用形式为我的用户的用户角色,设置的has_many:通过与在轨道上的表单3

<%= form_for @user do |f| %> 
    <%= f.error_messages %> 
    <p> 
    <%= f.label :username %><br /> 
    <%= f.text_field :username %> 
    </p> 
    <p> 
    <%= f.label :email, "Email Address" %><br /> 
    <%= f.text_field :email %> 
    </p> 
    <p> 
    <%= f.label :password %><br /> 
    <%= f.password_field :password %> 
    </p> 
    <p> 
    <%= f.label :password_confirmation, "Confirm Password" %><br /> 
    <%= f.password_field :password_confirmation %> 
    </p> 

    <% # f.select :roles, Role.all.map {|r| [r.title]} %> 

    <% Role.all.each do |role| %> 
    <div> 
     <%= check_box_tag :role_ids, role.id, @user.roles.include?(role), :name => 'user[role_ids][]' -%> 
     <%= label_tag :role_ids, role.title -%> 
    </div> 
    <% end -%> 

    <p><%= f.submit (@user.new_record? ? "Sign up" : "Update"), :id => :sign_up %></p> 
<% end %> 

这是我在我的模型协会

class user < ActiveRecord::Base 
    has_many :assignments 
    has_many :roles, :through => :assignments 
end 

class assignment < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :role 
end 

class role < ActiveRecord::Base 
    has_many :assignments 
    has_many :users, :through => :assignments 
end 

通过使用我在开始介绍的表单创建用户和角色之间的分配的方式是什么?

我在我的用户控制器创建操作是这样的:

def create 
    @user = User.new(params[:user]) 
    if @user.save 
     session[:user_id] = @user.id 
     render :action => 'dashboard' 
    else 
     render :action => 'new' 
    end 
    end 

当我把我的形式,我得到的错误:

的ActiveRecord :: AssociationTypeMismatch在UsersController#创建

角色(# 70331681817580)预计得到String(#70331650003400)

Request 

Parameters: 

{"utf8"=>"✓", 
"authenticity_token"=>"WHpOW+DmymZ2pWmY9NHSuodf2vjyKdgMNZcc8NvCNa0=", 
"user"=>{"username"=>"ioio", 
"email"=>"[email protected]", 
"password"=>"[FILTERED]", 
"password_confirmation"=>"[FILTERED]", 
"roles"=>["2"]}, #### <<< ==== This is the checkbox that I selected for this request. 
"commit"=>"Sign up"} 

欢迎任何帮助。

+0

运气好的解决方案?该修补程序适用于我,所以我很好奇它是否也解决了您的问题。 – miked 2012-02-02 19:21:07

回答

4

使用当前的形式和依据:

<%= check_box_tag :role_ids, role.id, @user.roles.include?(role), :name => 'user[role_ids][]' -%> 

在提交时,您的PARAMS应该像(注意 'role_ids' 而不是 '角色'):

Request 

Parameters: 

{"utf8"=>"✓", 
"authenticity_token"=>"WHpOW+DmymZ2pWmY9NHSuodf2vjyKdgMNZcc8NvCNa0=", 
"user"=>{"username"=>"ioio", 
"email"=>"[email protected]", 
"password"=>"[FILTERED]", 
"password_confirmation"=>"[FILTERED]", 
"role_ids"=>["2"]}, #### <<< ==== This is the checkbox that I selected for this request. 
"commit"=>"Sign up"} 

如果是这样的情况下,您将不得不实例化您的角色并将它们设置为控制器中的用户:

def create 
    @user = User.new(params[:user]) 
     roles = Role.find(params[:user][:role_ids]) rescue [] 
     @user.roles = roles 
    if @user.save 
      session[:user_id] = @user.id 
      render :action => 'dashboard' 
    else 
      render :action => 'new' 
    end 
  end 

... and simil arly:

def update 
    @user = User.where(:username=>params[:id]).first 
    roles = Role.find(params[:user][:role_ids]) rescue [] 
    @user.roles = roles 
    if @user.update_attributes(params[:user]) 
     redirect_to users_url, :notice => "Successfully updated user." 
    else 
     render :action => 'edit' 
    end 
    end 
0

错误消息给出了提示:为了能够保存用户对象,您首先需要以某种方式创建关联的角色对象。目前,您只有一个字符串数组是Role ID。

您需要在用户模型上使用accepts_nested_attributes_for方法。

+0

我试图在用户模型(user.rb)中添加accep_nested_attributes_for:roles,但没有运气。 – Goles 2012-01-30 22:12:16

+0

@ Mr.Gando看@miked答案 - 他正确地指出你需要'role_ids',而不是'roles'作为params散列(和复选框)中的键。然后,可以通过在用户模型上使用'accep_nested_attributes_for'来进一步简化代码。 – maprihoda 2012-01-31 10:06:29