基于 ActiveRecord 验证错误的决策

发布于 2024-12-14 20:07:56 字数 932 浏览 0 评论 0原文

我对 Rails 很陌生,想知道最好的方法是什么:

我有一个控制器在数据库中创建一条记录。

如果发生特定的验证错误,我想设置一个标志,但我看不到使用我熟悉的 Rails 模式来完成此操作的好方法。

我想要检测的模型验证是:

validates_uniqueness_of :title

我的控制器正在执行以下操作:

fcs = Entity.create(:title => text)

当上述错误失败时,我有一个 ActiveModel 错误集合可以使用。

我应该如何可靠地设置一个标志来以编程方式指示标题已被占用?

到目前为止,我已经考虑过,

fcs.errors.messages.has_key?(:title)

但如果标题因其他原因失败,这将返回 true。所以我需要更多类似的东西:

fcs.errors.messages[:title]==["has already been taken"]

但这将是一个令人头痛的维护问题,而且也会被不同的区域设置所破坏......

所以有人知道这应该如何用 RoR 来完成吗?

感谢您的任何建议

编辑:建议标志“is_title_duplicate”的示例用法:

if(! fcs.errors.empty?)
      json['success']=false
      json['errors']=fcs.errors.full_messages
      json['title_was_duplicate'] = is_title_duplicated
      render :json => json

...

I'm very new to rails and am wondering what the best way to do this is:

I have a controller creating a record in the database.

If a specific validation error occurs I want to set a flag, and I can't see a good way to accomplish this with the rails patterns I am familiar with.

The models validation that I want to detect is:

validates_uniqueness_of :title

My controller is doing this:

fcs = Entity.create(:title => text)

When the above error fails I have an ActiveModel errors collection to work with.

How should I go about reliably setting a flag to indicate programatically that the title has been taken?

So far I've considered

fcs.errors.messages.has_key?(:title)

But this will return true if title has failed for some other reason. So I would need something more like:

fcs.errors.messages[:title]==["has already been taken"]

But that would be a maintenance headache and would also be broken by different locales...

So does anyone know how this should be done with RoR?

Thanks for any advice

edit: Example usage of proposed flag "is_title_duplicated":

if(! fcs.errors.empty?)
      json['success']=false
      json['errors']=fcs.errors.full_messages
      json['title_was_duplicate'] = is_title_duplicated
      render :json => json

...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

美煞众生 2024-12-21 20:07:56

我建议向您的模型类添加一个方法来检测唯一性。

class Entity < ActiveRecord::Base
  def unique_title?
    Entity.where(:title => title).count > 0
  end
end

当然,这意味着您要运行该查询两次(一次针对 validates_uniqueness_of,一次针对 unique_title?)。只要性能可以接受,我更喜欢可读性而不是性能。如果性能不可接受,您仍然有选择。您可以在自己的自定义验证中重复使用 unique_title? 并缓存结果。

class Entity < ActiveRecord::Base
  validate :title_must_be_unique

  def unique_title?
    # you may want to unset @unique_title when title changes
    if @unique_title.nil?
      @unique_title = Entity.where(:title => title).count > 0
    end
    @unique_title
  end

  private

  def title_must_be_unique
    unless unique_title?
      errors.add(:title, I18n.t("whatever-the-key-is-for-uniqueness-errors"))
    end
  end
end

I recommend adding a method to your model class to detect uniqueness.

class Entity < ActiveRecord::Base
  def unique_title?
    Entity.where(:title => title).count > 0
  end
end

Of course, this would mean that you're running that query twice (once for the validates_uniqueness_of and once for unique_title?). I prefer readability over performance as long as the performance is acceptable. If the performance is not acceptable, you still have options. You can re-use unique_title? in your own custom validation and cache the result.

class Entity < ActiveRecord::Base
  validate :title_must_be_unique

  def unique_title?
    # you may want to unset @unique_title when title changes
    if @unique_title.nil?
      @unique_title = Entity.where(:title => title).count > 0
    end
    @unique_title
  end

  private

  def title_must_be_unique
    unless unique_title?
      errors.add(:title, I18n.t("whatever-the-key-is-for-uniqueness-errors"))
    end
  end
end
巴黎盛开的樱花 2024-12-21 20:07:56

你的意思是在记录上设置一个标志吗?每当验证失败时,记录都不会保存到数据库中。

如果您只是想设置错误消息,则不必这样做。 Rails 会自动将 fsc.erros 设置为类似 {:title =>; 的哈希值。 “标题已被占用”}。您可以通过将 :message 传递给验证来指定该消息。

此外,您还可以使用 l18n 将消息国际化。只需按照此处所述编辑 yaml 文件:
http://guides.rubyonrails.org/i18n.html#configure-the -i18n-模块

Do you mean set a flag on the record? Whenever a validation fails the record is not saved to the database

If you just mean setting the error message, you don't have to. Rails will automatically set fsc.erros to be a hash that looks like {:title => "title has already been taken"}. You can specify that message by passing :message to your validation.

Also, you can internationalize the messages by using l18n. Just edit the yaml file as described here:
http://guides.rubyonrails.org/i18n.html#configure-the-i18n-module

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文