所以我明白我可以写
validates :column_name, uniqueness: :true
我可以测试一个字段是否唯一。但如果不是上述应用程序会抛出错误。我希望能够通过添加整数使其独一无二而不是抛出错误。
该属性称为' legacy_code'。代码由标题措辞的第一个字母生成,并通过
调用 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
那么如何在文章类中实现这种功能呢?
由于
答案 0 :(得分:2)
你可以尝试:
before_validate :generate_article_legacy_code
确保如果代码存在,则generate方法不执行任何操作。
答案 1 :(得分:2)
如果有一篇文章的标题首字母缩略词有多个副本怎么办?比如说有3个副本,title_acron在第二个或第三个查找中不是唯一的,你最终会得到ABC,ABC1,ABC2。这就是你想要的。但如果标题以数字结尾,则会发现问题。你可以有(ABC1),(ABC1)1,(ABC1)2 ......等等,但是当你想增加首字母缩略词时,你不能在不做一些工作的情况下判断它是1还是11在手之前。这会变得混乱。
我会将标题和一个名为number的列组合在一起。所以在Rails 4模型中你会有这样的东西
validates :title_acronym, uniqueness: {scope: :number}
每当弹出一个具有相同title_acronym的文章时,该文章就会需要 适当地设置它自己的数字计数器。您可以在名为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
也可以在数据库级别强制执行唯一性,但这可能不是必需的。
如果你想通过legacy_code查找单个记录,那么现在存在一个根本问题。假设有title_acronym ABC和另一个title_acronym ABC1。由于这些是title_acron的第一个,因此title_acron和legacy_code是相同的。如果还有另一篇带有title_acronym ABC的文章,那么其legacy_code必须成为ABC1,但这并不是唯一的,因为legacy_code已经存在。
这就是说,如果你不能保证标题不以数字结尾,你就不能使用legacy_code可靠地搜索一个独特的记录,因为它的本质是legacy_code赢了& #39; t产生独特的价值。您需要使用title_acronym和number搜索唯一记录。我假设标题可以以数字结尾,因为你毕竟是在处理文章。
如果您愿意更改legacy_codes的外观以获得唯一性。您可以在title_acronym和number之间添加分隔符。我在这个例子中使用了下划线。
if self.number == 0
self.legacy_code = "#{self.title_acronym}"
else
self.legacy_code = "#{self.title_acronym}_#{self.number}"
end
legacy_codes现在保证是唯一的,因为它由保证唯一的部分和分隔符组成,但是您可以将其添加到适当的位置。
validates :legacy_code, uniqueness: :true
答案 2 :(得分:0)
您可以检查记录是否有效。如果它不是vaild,则添加整数,然后重试。像这样:
if(@article.valid?)
@article.save!
# do whatever
else
# add integer
end