通过关联管理has_many中的记录的最佳做法是什么?

时间:2016-10-01 20:49:10

标签: ruby-on-rails activerecord

我有三个模型:User,Group和GroupUser

class User < ActiveRecord::Base
  has_many :group_users
  has_many :groups, through: :group_users

class Group < ActiveRecord::Base
  has_many :group_users
  has_many :users, through: :group_users

class GroupUser < ActiveRecord::Base
  belongs_to :group
  belongs_to :user`

我创建了一个给定组的表单,其中包含所有用户的复选框,因此我可以看到每个用户是否都在该组中,我可以检查任何用户是否添加到组或取消选中用户是否属于组。然后在提交表单后,我会得到一组用户的id。

我的问题是:在提交操作(多个添加/删除记录)之后将这样的代码编写到控制器或其他地方的最佳方法是什么。

为此,我在GroupsController中创建了两个额外的操作:def select_users用于打开复选框表单,def add_users用于添加和删除。

  def select_users
    @group = Group.find(params[:id])
  end

  def add_users
    @group = Group.find(params[:id])
  # Add new users
    new_users = params[:group][:user_ids]
    old_users = @group.users.map {|x| x.id.to_s } + [""]
    add_users = new_users.reject { |item| old_users.include?(item) }

    add_users.each do |id|
      @group.users << User.find(id)
    end

# Delete unwanted users
    delete_users = old_users.reject { |item| new_users.include?(item) }
    @group.group_users.where(user_id: delete_users).destroy_all

    redirect_to groups_path, notice: 'Users were added.'

  end`

我本可以为连接表创建控制器GroupUser,并将这些操作放在RESTful'new'和'create'中,但我不确定这是最好的方法。

2 个答案:

答案 0 :(得分:0)

1)不要在GroupsController中做所有这些事情 - 它让它变得混乱。创建一个新的普通ruby类来处理它。

2)不确定,但我打赌你可以将用户分配到一个集合,它将写入该关联。就这样:

@group.users = User.where(id: [1,2,4]) # you can just give it your params[:group][:user_ids] here as the array
@group.save! # also not sure if this is necessary

答案 1 :(得分:0)

最佳做法是拥有一个瘦小的控制器和一个胖子模型。所以我不会把这两种方法放在你的控制器上。控制器应该理想地调用单个模型方法。所以我会改变这个:

def add_users


@group = Group.find(params[:id])
  # Add new users
  new_users = params[:group][:user_ids]
  old_users = @group.users.map {|x| x.id.to_s } + [""]
  add_users = new_users.reject { |item| old_users.include?(item) }

  add_users.each do |id|
    @group.users << User.find(id)
  end
end

关于群组模型的内容

def update_users(user_ids)
  new_users = User.where(id: user_ids)
  final_users = new_users + self.users
  self.users = final_users.uniq
  self.save
end

就restful约定而言,我会将其放在groups控制器的更新操作上,并使用accepts_nested_attributes_for选项。

def update
  @group = Group.find(params[:id])
  if @group.update_users(params[:group][:user_ids])
    #handle success
  else
   #handle error
  end
end