Ruby On Rails多选择器具有多对多的关系

时间:2012-05-24 19:07:06

标签: ruby-on-rails ruby-on-rails-3 many-to-many html-select

我有两个型号

项目 ,其中包含has_and_belongs_to_many:用户

用户 ,其中包含has_and_belongs_to_many:projects

在项目视图中我有一个表单,其中包含一个选择器,我想尝试将多个用户分配给项目。

<%= select_tag("project[users]",  options_for_select(@users, @project_users), {:multiple=>true, :size=>6} )%>

在我的项目控制器中,在select中使用的变量是

@project_users = @project.users.collect { |user| user.id}
@users = User.all.collect { |user| ["#{user.first_name} #{user.last_name}", user.id] }

全部放出

<select id="project_users" multiple="multiple" name="project[users][]" size="6">
   <option value="#<User:0x007f567cb7f078>">User1</option>
   <option value="#<User:0x007f567cb7e9c0>">User2</option>
</select>

问题是这不等于

@some_project << [User(#), User(#)]

(“注意用户(#)代表类实例”)

相当于

@some_project << ["1", "2"]

问题是用户实例被转换为字符串但不再返回实例。

哪个不起作用并将抛出错误

ActiveRecord::AssociationTypeMismatch in ProjectsController#update
User(#70004716784160) expected, got String(#4266680)

如何才能正常运作?

2 个答案:

答案 0 :(得分:4)

在您的用户模型中:

def full_name
  [first_name, last_name].join(" ")
end

在您的控制器中

@users = User.all

在您看来:

<%= select_tag('project[user_ids]', options_from_collection_for_select(@users, 'id', 'full_name'), { :multiple => true, :size => 6 }) %>

然后你可以使用

@project.user_ids = params[:project][:user_ids]

@project.update_attributes(params[:project])

进行作业。

答案 1 :(得分:2)

您无法发送实例。它可以在表单的呈现和提交之间进行更改。转换为字符串是单向操作,因为它引用了对象的唯一ID(如内存地址),而不是它的属性或数据库标识符!因为它不是ActiveRecord的一部分,而是ruby的对象基础。当返回表单的数据时,实例不在内存中,因此您无法将其转换回来,即使可能的话也是如此。

坚持原来的方式:

@project_users = @project.users.collect { |user| user.id}
@users = User.all.collect { |user| ["#{user.first_name} #{user.last_name}", user.id] }

提交数据时:

@users = params[:project][:users].map{|a| User.find(a) }