Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 在添加关联回调之前以静默方式跳过添加,而不是引发异常?_Ruby On Rails_Activerecord_Callback - Fatal编程技术网

Ruby on rails 在添加关联回调之前以静默方式跳过添加,而不是引发异常?

Ruby on rails 在添加关联回调之前以静默方式跳过添加,而不是引发异常?,ruby-on-rails,activerecord,callback,Ruby On Rails,Activerecord,Callback,我正试着这么做 has_many :roles, :before_add => :enforce_unique def enforce_unique(assoc) false if exists? assoc end 文档中写道:“如果before_add回调引发异常,则该对象不会添加到集合中”。上面的使用false并不能阻止添加,因此我不得不这样做: def enforce_unique(assoc) raise if exists? assoc end 这样

我正试着这么做

 has_many :roles, :before_add => :enforce_unique

 def enforce_unique(assoc)
   false if exists? assoc
 end
文档中写道:“如果before_add回调引发异常,则该对象不会添加到集合中”。上面的使用false并不能阻止添加,因此我不得不这样做:

 def enforce_unique(assoc)
   raise if exists? assoc
 end
这样,它确实不会被添加,但它也会引发一个必须处理的异常。在这里对我不是很有用。我希望它的行为更像保存前的常规AR回调,返回FALSE也可以防止保存(或添加),但不会引发异常


在上面的这种情况下,我宁愿这样做,也不要默默地添加assoc。有办法做到这一点吗?我错过了什么?或者引发异常是这里唯一的选项吗?

如果关联不是多态的,您可以执行以下操作:

validates_uniqueness_of :name_of_model

这个问题有点老了,但我最近遇到了同样的问题。我是这样解决的:

def enforce_unique |obj, x|
  v = obj.roles
  if i = v.index(x)
    v.slice! i
  end
end

我认为解决这个问题的方法是使用
throw
catch
,它们在Ruby中用于流控制。提出异常并不合适,因为这不是异常情况

我最后做了:

catch(:duplicate) do
  association.create({})
end
然后在添加之前的
回调中,我做了:

if(Class.where({}).first)
  throw :duplicate
end
更多关于投掷/接球的信息,请点击此处:


由于此问题是关于保存而不是临时阻止它被包括在列表中(例如由一个对控制其模型不感兴趣的控制器),您可以尝试覆盖相关模型中的保存,如果角色存在,则不保存它:

class Role < ActiveRecord::Base
  belongs_to :user, inverse_of: :roles

  def save
    super unless self.new_record? && user.has_existing_role?(self)
  end
end
类角色
旁注:当与活动记录模式一起使用时,我不相信skinny controller参数,因为业务逻辑必须放在某个地方。对于像activerecord这样的业务领域糟糕的模式(不具体指Ruby AR gem),它确实需要在上面存在一层(即控制器层),您可以使用服务对象或装饰器模式作为实现这一点的手段

另一种方法是覆盖更新方法,如