Rails: activerecord 更新到新关联

Rails: activerecord update to new association

我有两个模型:用户和角色。一个用户可以有多个角色。

假设user1有role1和role2。现在我想让 user1 拥有 role2 和 role3。

class User < ActiveRecord::Base

  has_and_belongs_to_many :roles

class Role < ActiveRecord::Base

  has_and_belongs_to_many :users

这是我的代码

user = User.find(1) 
newrole = Role.find(2) #get role3 

user.roles[0] = newrole 

user.roles[0].save  # does not work 

user.save # does not work 

rails ruby 中解决我的问题的正确方法是什么?

user.roles.destroy(Role.find(1)) # assuming Role.find(1) == role1
user.roles << Role.find(3) # assuming Role.find(3) == role3

与其将记录从 role1 更新到 role3,更简单的方法是删除 role1 的记录并为 role2 创建新记录。

对于 has_and_belongs_to_many,您只需要传递 ID,rails 会自动处理它。

示例:

对于 Rails 控制台:

-> @user = User.first
-> puts @user.role_ids
   # [1,2]

-> @user.role_ids = [2, 3]

这将通过删除 role1 并为 role3

创建记录来为用户分配新角色

edit.html.erb(查看):

假设您有一个 User 的表单,并且有一个 roles 的下拉列表,其中包含多个 selection

<%= form_for(book) do |f| %>
  <div class="field">
    <%= f.label :first_name %>
    <%= f.text_field :first_name %>
  </div>

  <div class="field">
    <%= f.label :roles %>
    <%= f.collection_select :role_ids, Role.all, :id, :name, {}, {:multiple => true} %>
  </div>

  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

users_controller.rb(控制器):

def update
  respond_to do |format|
    if @user.update(user_params)
      format.html { redirect_to @user, notice: 'User was successfully updated.' }
      format.json { render :show, status: :ok, location: @user }
    else
      format.html { render :edit }
      format.json { render json: @user.errors, status: :unprocessable_entity }
    end
  end
end

private

def user_params
    params.require(:user).permit(:first_name, :last_name, role_ids: [])
end

现在,当您 select role2role3 提交表单时,Rails 只需删除 role1 和为 role3

创建另一个