Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/65.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 Rails:忽略某些记录验证唯一性_Ruby On Rails - Fatal编程技术网

Ruby on rails Rails:忽略某些记录验证唯一性

Ruby on rails Rails:忽略某些记录验证唯一性,ruby-on-rails,Ruby On Rails,我们正在使用RubyonRails4 我的“事件”模型有: “标题”字段,可以是任意字符串 作为约定表索引的约定id字段 一个状态字段,可以是“提议”、“讨论”、“接受”、“拒绝”或“放弃” 我想创建一个validates语句,以确保标题在约定中是唯一的。这是最简单的部分 validates :title, :uniqueness => { :scope => :convention_id } 做我想做的事。但我想忽略任何状态为“已拒绝”或“已删除”的记录。我真正想要的是向SQ

我们正在使用RubyonRails4

我的“事件”模型有:

  • “标题”字段,可以是任意字符串
  • 作为约定表索引的约定id字段
  • 一个状态字段,可以是“提议”、“讨论”、“接受”、“拒绝”或“放弃”
我想创建一个validates语句,以确保标题在约定中是唯一的。这是最简单的部分

validates :title, :uniqueness => { :scope => :convention_id }
做我想做的事。但我想忽略任何状态为“已拒绝”或“已删除”的记录。我真正想要的是向SQLRails生成的语句中添加一些WHERE子句,但我不确定如何添加

感谢您的帮助。

,您可以通过带有排除条件的:

validates :title, 
  uniqueness: {scope: :convention_id},
  unless: Proc.new { |event| event.status == "Rejected" || event.status == "Dropped" }
请注意,哈希火箭(
=>
)的使用必须一致。在上面的示例中,我用JSON样式的符号替换了hash rocket语法(事实上是Rails 4的符号),但是可以重写整个语句以使用hash rocket,如下所示:

validates :title, 
  :uniqueness => {:scope => :convention_id},
  :unless => Proc.new { |event| event.status == "Rejected" || event.status == "Dropped" }

我找到了答案。以下内容似乎与我预期的一样有效:

validates_uniqueness_of :title,  
  scope: :convention,  
  conditions: -> { where.not(status: ['Dropped', 'Rejected']) }
生成的SQL是

SELECT 1 AS one FROM "events"
  WHERE ("events"."title" = 'Panel' AND 
         "events"."id" != 2 AND 
         "events"."convention_id" = 1) AND
        ("events"."status" NOT IN ('Dropped', 'Rejected'))
  LIMIT 1
我想这正是我想要的


再次感谢您的帮助。

使用
验证创建验证的另一种方法可能是


到目前为止,这方面有什么进展吗?我认为您需要编写自定义验证来实现这一点,除非您引入另一个专栏,否则我们称之为
活动
。如果前三个状态为活动状态,后两个状态为非活动状态,则可以使用作用域
:scope=>[:convention\u id,:active]
,当然,然后
active
会复制
status
列中的信息,这通常是个坏主意。我将开始探索如何编写自定义验证。谢谢。请澄清一下,当您说要忽略已拒绝或已删除的记录时,您的意思是什么?状态设置为“已拒绝”或“已删除”的记录可以有重复的标题。但这不起作用。它失败了,错误为{:title=>[“已被接受”]},development.log没有显示SQL上的WHERE子句。我认为这与OP想要的相反。OP询问,如果标题在约定范围内是唯一的,则对象是否有有效的方法,除了
拒绝的
放弃的
之外。您编写的内容将允许添加被拒绝/删除的记录。按照我对问题的解释,OP希望验证未被拒绝或删除的记录,这就是它应该做的。坦率地说,这个问题措辞不好。@user2062850,为什么需要
WHERE
子句?我已经检查了此查询,它确实应该达到您在问题和后续评论中指定的预期结果。
WHERE
子句用于跳过对状态为“拒绝”或“已删除”的事件的检查。我创建了一个事件,将其状态设置为“已删除”并保存。然后,我创建了第二个标题相同的事件,并试图保存它。上面的代码拒绝了第二次保存,因为它与第一个事件的标题相匹配,尽管状态设置为“已删除”。下面使用
conditions
子句的解决方案在SQL中添加了一个
WHERE
子句,以跳过查看任何状态为“drop”或“Rejected”的行,因此第二次保存成功。我提供的答案生成了一个更简洁的SQL查询。您能否说明此答案如何更有效地满足您的问题?使用除非子句的解决方案是检查正在验证的事件,而不是与数据库中已有的事件进行比较。因此,当我创建一个事件并将其状态设置为dropped,然后创建第二个事件时,第二次保存失败,因为它正在查找匹配项。使用conditions子句,第二次保存成功,因为第一个事件的状态为“Dropped”,并且与查询不匹配。
validates :title,
          uniqueness: { scope: :convention, conditions: -> { where.not(status: ['Dropped', 'Rejected']) }