【问题标题】:Rails association : update association parameter (make admin/remove admin)Rails 关联 : 更新关联参数 (make admin/remove admin)
【发布时间】:2014-03-27 10:09:14
【问题描述】:

所以我有一个User 模型和一个Group 模型,由于GroupUserAssociation 模型有几个users。我的关系是这样定义的:

class Group < ActiveRecord::Base
  has_many :group_users, :class_name => 'GroupUserAssociation', :foreign_key => :group_id
  has_many :group_admins, :class_name => 'GroupUserAssociation', :foreign_key => :group_id, :conditions => ['level = 1']
  has_many :group_not_admins, :class_name => 'GroupUserAssociation', :foreign_key => :group_id, :conditions => ['level = 0']

  has_many :users, :through => :group_users, :source => :user
  has_many :admins, :through => :group_admins, :source => :user
  has_many :not_admins, :through => :group_not_admins, :source => :user
end

如果我想在组中添加/删除用户,有一种优雅的方式来编写它(优雅,因为它不涉及GroupUserAssociation 对象):

Group.first.users << User.first # Adds to group
Group.first.users.delete(User.first) # Removed from group

如果我这样做了

Group.first.admins << User.first
Group.first.admins.delete(User.first)

它还会删除关联(因此与第一行具有相同的效果)。

有没有一种优雅的方式(无需处理GroupUserAssociation 对象来提升/降级管理员(= 将GroupUserAssociation.level 从1 更新为0)?

我可以的

Group.first.users.delete(User.first) # Removed from group
Group.first.admins << User.first

但这意味着 2 次提交到数据库,这并不是很好......

我读到 Rails 4 中有一些不错的东西,但不幸的是我使用的是 Rails 3.2...

谢谢

【问题讨论】:

  • 看起来您的代码基本上按照您阅读的方式运行?我不明白你希望它如何工作?我在答案中添加了代码,显示了我们使用的内容
  • 不,Group.first.admins.delete(User.first) 删除成员,并且不更新协会的可见性......但我认为这个问题回答了我的问题:stackoverflow.com/questions/13370013/…
  • 酷好吧 - 我更新了我们用于您阅读的代码
  • 我不熟悉任何可以处理此问题的 Rails 4 功能。我能想到的最简单的方法是Group.first.group_users.find_by(user_id: 1).update_column(:level, 1)。它应该很简单,并且只写入数据库一次。
  • 另一种解决方案是为group_user 模型实现demotepromote 方法。这些方法只会减少/增加level 列。

标签: ruby-on-rails ruby-on-rails-3 activerecord


【解决方案1】:

我们使用以下代码来做这件事:

#config/routes.rb
resources :entries do
   post :category
   delete ":category_id", to: :category, as: "remove_category"
end

#Categories
def category
    entry = @entry = Entry.find(params[:entry_id])
    category = @category = Category.find(params[:category_id])

    #Actions
    entry.categories << category if request.post? && !entry.categories.include?(category)
    entry.categories.delete(category) if request.delete?

    #Return
    respond_to do |format|
        format.html { redirect_to collection_path }
        format.js
    end
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多