使用作用域验证值的唯一性 - Ruby on Rails 5

23
我有一个名为posts的表格,并带有一个名为Post的模型,还有一个名为languages的表格(列 - id、post_id、language),并且有一个名为Language的模型。文章有许多语言,而语言属于一篇文章。在文章模型中我有:

文章模型:

has_many :languages
validates_associated :languages

语言模型:

belongs_to :post
validates_uniqueness_of :language, scope: :post_id

语言是表格“languages”中的列。

在posts_controller(strong parameters)中允许language字段:

def post_params
    params.require(:post).permit(:languages_attributes => [:language], ...)

这是创建帖子表单的视图:

<%= form_for @post do |f| %>
    .....
    <%= f.fields_for :languages do |language| %>
        <%=language.select :language, ['english', 'italian', 'french', 'spanish'], name: 'post[languages_attributes][][language]' %>
        <%=language.select :language, ['english', 'italian', 'french', 'spanish'], name: 'post[languages_attributes][][language]' %>
        <%=language.select :language, ['english', 'italian', 'french', 'spanish'], name: 'post[languages_attributes][][language]' %>
        <%=language.select :language, ['english', 'italian', 'french', 'spanish'], name: 'post[languages_attributes][][language]' %>
    <% end %>

这是创建文章的方法:

@post= Post.new(post_params)
if @post.save
....

我希望验证post_id范围内语言的唯一性,并且每篇文章只有一种英语语言。文章可以有多种语言,但是不同的语言。

我尝试使用validates_uniqueness_of :language, scope: :post_id,但是如果我两次添加英语(全部小写),则不会出现错误,数据将被插入到表中。

如何验证当前文章范围内语言的唯一性?

编辑:我看到这是Rails中的一个bug - GitHub,但我仍然需要解决方案。


1
请告诉我您的语言模型中要验证唯一性的语言表中的哪一列。我认为它不被称为“language”。 - Pranav Singhal
它被称为“语言”。 - gdfgdfg
这个回答解决了你的问题吗?验证多列的唯一性 - potashin
2个回答

30
如何在Rails 5中验证两个列的唯一性?这是答案。
validates :username, uniqueness: { scope: :group_id }
如果您需要记录唯一,请为记录添加唯一索引。
class AddUniqueIndexToRoles < ActiveRecord::Migration[5.2]
  def change
    add_index :roles, [:username, :group_id], unique: true
  end
end

9
我没有完全理解你的问题,但如果你无法通过以下方式验证唯一性
validates_uniqueness_of :language, scope: :post_id

然后你可以尝试以下的方法
validate :unique_language_id


def unique_language_id
  if post.languages.where(language: self.language).exist?
    error.add(:language_id, :taken)
  end
end

希望这对你有用...

*** NoMethodError 异常:#Class:0x12fb4c78没有定义languages'方法 必须使用validate而不是validates,并且是Post`。但我认为即使这样也会从数据库中选择值,但在此帖子(范围)的验证之前没有保存数据。我有父模型Post和子模型Language。我希望每个帖子只有唯一的语言。 - gdfgdfg
由于这个作用域 Post (scope: :post_id)。在 languages 表中,列 language 可能会有重复值,但是特定的 post 不会有重复值。 - gdfgdfg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接