【问题标题】:Setting has_many :through with a form on rails 3设置 has_many :through 在 rails 3 上使用表单
【发布时间】:2012-02-22 15:15:44
【问题描述】:

我正在尝试使用表单为我的用户创建用户角色,

<%= 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

当我发送表单时出现错误:

UsersController#create 中的 ActiveRecord::AssociationTypeMismatch

期望角色(#70331681817580),得到字符串(#70331650003400)

Request

Parameters:

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

欢迎任何帮助。

【问题讨论】:

  • 解决方案有什么好运气吗?该修复程序对我有用,所以我很好奇它是否也解决了您的问题。

标签: ruby-on-rails ruby-on-rails-3 has-many-through


【解决方案1】:

使用您当前的表格并基于:

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

提交时,您的参数应如下所示(注意“role_ids”而不是“roles”):

Request

Parameters:

{"utf8"=>"✓",
 "authenticity_token"=>"WHpOW+DmymZ2pWmY9NHSuodf2vjyKdgMNZcc8NvCNa0=",
 "user"=>{"username"=>"ioio",
 "email"=>"ioio@ioio.com",
 "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

...同样:

   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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 我尝试在用户模型 (user.rb) 中添加accepts_nested_attributes_for :roles,但没有成功。
    • @Mr.Gando 看看@miked 的答案——他正确地指出您需要role_ids,而不是roles 作为参数哈希(和复选框)中的键。然后,您可以通过在用户模型上使用accepts_nested_attributes_for 来进一步简化代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-27
    • 1970-01-01
    • 1970-01-01
    • 2011-03-06
    • 2011-10-22
    • 1970-01-01
    • 2015-03-19
    相关资源
    最近更新 更多