has_many,通过关系没有填充

时间:2016-05-05 06:04:14

标签: ruby-on-rails ruby activerecord

我正在尝试允许用户模式为其他用户添加和删除个别设置,但我无法使has_many ... through关系正常工作:我能够创建新的设置模式,但我无法检索或删除它们。

这是我的User.rb:

class User < ActiveRecord::Base
  has_many :settings, class_name:  "Setting",
                              foreign_key: "user_id",
                              dependent:   :destroy

  has_many :user_settings, through: :settings, source: :user

  def create_settings(user)
    settings.create(following_id: user.id)
  end

  def delete_settings(user)
    settings.find_by(following_id: user.id).destroy
  end

  def has_settings?(user)
    user_settings.include?(user)
  end
...

这是我的Setting.rb:

class Setting < ActiveRecord::Base
  belongs_to :user, class_name: "User"
  validates :user_id, presence: true
  validates :following_id, presence: true
end

我用这些users_controller函数调用创建/删除方法:

def add_settings
  user = User.find(params[:user_id])
  if !@user.has_settings?(user)
    @user.create_settings(user)
    @user.save
  end
end

def remove_settings
  user = User.find(params[:user_id])
  if @user.has_settings?(user)
    @user.delete_settings(user)
    @user.save
  end
end

如果我拨打add_settings然后remove_settings,我会同时收到成功回复,但如果我再次拨打add_settings,我会收到错误消息:

ActiveRecord::RecordNotUnique (PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint "index_settings_on_user_id_and_following_id"

因此,似乎User.rb中的has_settings始终返回false,并且在调用控制器函数remove_settings时永远不会删除用户设置。

为什么不填充user_settings关系?如何让has_settings返回正确的值?

1 个答案:

答案 0 :(得分:2)

user_settings.include?(user)将始终返回false,因为user_settingsuser_setting个对象的集合,而不是user个对象。此外,在这里调用include?可能效率不高,因为它需要将多个user_settings对象加载到内存中以比较每个对象。

根据user_settingssettings的定义方式,您应该能够使用以下查询来检查是否有属于此用户的user_settings self })。请尝试以下查询:

def has_settings?(user)
  settings.exists?(following_id: user.id)
end