Ruby on rails rails检查唯一性并处理条件
所以我知道我会写作Ruby on rails rails检查唯一性并处理条件,ruby-on-rails,ruby,Ruby On Rails,Ruby,所以我知道我会写作 validates :column_name, uniqueness: :true 我可以测试一个字段是否唯一。但是如果不是,上面的应用程序就会抛出一个错误。我不想抛出一个错误,而是希望通过添加一个整数使其唯一 该属性称为“遗留_代码”。代码由标题措辞的第一个字母生成,并通过 after_create :generate_article_legacy_code 所以我写的测试是这样的 @article = FactoryGirl.create :article, ti
validates :column_name, uniqueness: :true
我可以测试一个字段是否唯一。但是如果不是,上面的应用程序就会抛出一个错误。我不想抛出一个错误,而是希望通过添加一个整数使其唯一
该属性称为“遗留_代码”。代码由标题措辞的第一个字母生成,并通过
after_create :generate_article_legacy_code
所以我写的测试是这样的
@article = FactoryGirl.create :article, title: 'Big Cheesey Pudding Yum Yum'
@article_one = FactoryGirl.create :article, title: 'Blue Chaffinches Purchased Yoko Yamamoto'
it "should be unique" do
expect(@article.legacy_code).to eq('BCPYY')
expect(@article_one.legacy_code).to eq('BCPYY1')
end
validates :title_acronym, uniqueness: {scope: :number}
那么如何在article类中实现这种功能呢
谢谢您可以检查记录是否有效。如果不可用,请添加整数并重试。大概是这样的:
if(@article.valid?)
@article.save!
# do whatever
else
# add integer
end
您可以检查记录是否有效。如果不可用,请添加整数并重试。大概是这样的:
if(@article.valid?)
@article.save!
# do whatever
else
# add integer
end
你可以试试:
before_validate :generate_article_legacy_code
确保如果代码存在,则generate方法不执行任何操作。您可以尝试:
before_validate :generate_article_legacy_code
确保如果代码存在,则generate方法不执行任何操作。那么,如果一篇文章的标题的首字母缩略词有多个副本,该怎么办?例如,假设有3个副本,第二次或第三次查找时标题_的首字母缩略词不会是唯一的,您将以ABC、ABC1、ABC2结尾。这就是你想要的。但是如果标题以数字结尾,您会发现一个问题。你可以有(ABC1),(ABC1)1,(ABC1)2。。。以此类推,但当你想增加首字母缩写词时,如果不事先做一些工作,你就无法判断它是1还是11。这会变得一团糟 我会把标题和一个名为number的列放在一起。因此,在Rails 4模型中,您可能会遇到类似的情况
@article = FactoryGirl.create :article, title: 'Big Cheesey Pudding Yum Yum'
@article_one = FactoryGirl.create :article, title: 'Blue Chaffinches Purchased Yoko Yamamoto'
it "should be unique" do
expect(@article.legacy_code).to eq('BCPYY')
expect(@article_one.legacy_code).to eq('BCPYY1')
end
validates :title_acronym, uniqueness: {scope: :number}
无论何时,只要出现一篇标题与首字母缩略词相同的文章,该文章就只需要
适当地设置它自己的数字计数器。您可以在模型上创建一个名为legacy_code的属性,该属性返回您想要的这两者的并集。完整代码如下所示
validates :title, presence: :true
validates :title_acronym, presence: true
validates :number, presence: true
validates :legacy_code, presence: true
validates :title_acronym, uniqueness: {scope: :number}
before_validate :setupArticle
def setupArticle
generate_title_acronym
generate_number
generate_legacy_code
end
def generate_title_acronym
if self.title.nil?
return nil
end
#Code to set the title_acronym from the title
end
def generate_number
if self.title_acronym.nil?
return nil
end
self.number = Article.where(title_acronym, title_acronym).maximum(:number) || 0
end
def generate_legacy_code
if self.title_acronym.nil? || self.number.nil?
return nil
end
if self.number == 0
self.legacy_code = "#{self.title_acronym}"
else
self.legacy_code = "#{self.title_acronym}#{self.number}"
end
end
唯一性也可以在DB级别强制执行,但这可能不是必需的
现在,如果您想通过遗留的_代码查找单个记录,那么这就有一个基本问题。假设有title_首字母缩写ABC和另一个title_首字母缩写ABC1。因为这是他们的title_首字母缩略词的第一个,所以他们的title_首字母缩略词和遗留_代码是相同的。如果有另一篇文章的标题是ABC,那么它的遗留代码必须成为ABC1,但这不是唯一的,因为遗留代码已经存在
这意味着,如果您不能保证标题不以数字结尾,那么您就无法使用遗留_代码可靠地搜索唯一的记录,因为从本质上讲,遗留_代码不会产生唯一的值。您需要使用title_首字母缩写和number搜索唯一的记录。我的工作假设标题可以以数字结尾,因为你毕竟是在处理文章
如果你愿意改变你的遗留代码的外观,以获得其独特性。您可以在title_首字母缩写和number之间添加分隔符。我在这个例子中使用了下划线
if self.number == 0
self.legacy_code = "#{self.title_acronym}"
else
self.legacy_code = "#{self.title_acronym}_#{self.number}"
end
遗留_代码现在保证是唯一的,因为它由保证是唯一的部分和一个分隔符组成,但您可以将其添加到适当的度量中
validates :legacy_code, uniqueness: :true
那么,如果一篇文章的标题的首字母缩略词有多个副本呢?例如,假设有3个副本,第二次或第三次查找时标题_的首字母缩略词不会是唯一的,您将以ABC、ABC1、ABC2结尾。这就是你想要的。但是如果标题以数字结尾,您会发现一个问题。你可以有(ABC1),(ABC1)1,(ABC1)2。。。以此类推,但当你想增加首字母缩写词时,如果不事先做一些工作,你就无法判断它是1还是11。这会变得一团糟 我会把标题和一个名为number的列放在一起。因此,在Rails 4模型中,您可能会遇到类似的情况
@article = FactoryGirl.create :article, title: 'Big Cheesey Pudding Yum Yum'
@article_one = FactoryGirl.create :article, title: 'Blue Chaffinches Purchased Yoko Yamamoto'
it "should be unique" do
expect(@article.legacy_code).to eq('BCPYY')
expect(@article_one.legacy_code).to eq('BCPYY1')
end
validates :title_acronym, uniqueness: {scope: :number}
无论何时,只要出现一篇标题与首字母缩略词相同的文章,该文章就只需要
适当地设置它自己的数字计数器。您可以在模型上创建一个名为legacy_code的属性,该属性返回您想要的这两者的并集。完整代码如下所示
validates :title, presence: :true
validates :title_acronym, presence: true
validates :number, presence: true
validates :legacy_code, presence: true
validates :title_acronym, uniqueness: {scope: :number}
before_validate :setupArticle
def setupArticle
generate_title_acronym
generate_number
generate_legacy_code
end
def generate_title_acronym
if self.title.nil?
return nil
end
#Code to set the title_acronym from the title
end
def generate_number
if self.title_acronym.nil?
return nil
end
self.number = Article.where(title_acronym, title_acronym).maximum(:number) || 0
end
def generate_legacy_code
if self.title_acronym.nil? || self.number.nil?
return nil
end
if self.number == 0
self.legacy_code = "#{self.title_acronym}"
else
self.legacy_code = "#{self.title_acronym}#{self.number}"
end
end
唯一性也可以在DB级别强制执行,但这可能不是必需的
现在,如果您想通过遗留的_代码查找单个记录,那么这就有一个基本问题。假设有title_首字母缩写ABC和另一个title_首字母缩写ABC1。因为这是他们的title_首字母缩略词的第一个,所以他们的title_首字母缩略词和遗留_代码是相同的。如果有另一篇文章的标题是ABC,那么它的遗留代码必须成为ABC1,但这不是唯一的,因为遗留代码已经存在
这意味着,如果您不能保证标题不以数字结尾,那么您就无法使用遗留_代码可靠地搜索唯一的记录,因为从本质上讲,遗留_代码不会产生唯一的值。您需要使用title_首字母缩写和number搜索唯一的记录。我的工作假设标题可以以数字结尾,因为你毕竟是在处理文章
如果你愿意改变你的遗留代码的外观,以获得其独特性。您可以在title_首字母缩写和number之间添加分隔符。我在这个例子中使用了下划线
if self.number == 0
self.legacy_code = "#{self.title_acronym}"
else
self.legacy_code = "#{self.title_acronym}_#{self.number}"
end
遗留_代码现在保证是唯一的,因为它由保证是唯一的部分和一个分隔符组成,但您可以将其添加到适当的度量中
validates :legacy_code, uniqueness: :true
如果删除记录,您可能会开始遇到此编号方案的问题-计数不会反映已经存在较大的数字。更好的方法是查找
max(:number)
,如果找不到,则使用“0”。您还需要注意,此解决方案不能解决同时传入的多个请求的并发问题。我明白您的意思,这可能会产生重复的旧\u代码。我来找钱。给你:)。该方法实际上是针对并发性调用的,ActiveRecord并没有提供一种很好的方法来实现ad