通过父属性进行 ActiveRecord 验证

发布于 2024-10-12 06:06:01 字数 1291 浏览 3 评论 0原文

例如,我有模型文章。文章有_一篇文章内容。默认情况下,ArticleContent 对其所有属性进行验证。但我需要额外的功能 - 保存草稿文章,而不进行任何验证。 所以我通过了:draft => false 作为 Article.new() 中的参数之一,接下来我执行 @article.build_article_content()。 ArticleContent 中有一些不起作用的代码:

  def draft?
    raise self.article.draft
  end

  validates_presence_of :header, :message => "We have no fuckin' header!", :unless => :draft?

当然它不起作用。在草稿的那一刻?执行时,任何地方都没有任何合适的 Article 对象,因此 self.article 返回 nil。不错的尝试,codemonkey...

有人有一些好主意吗?我想制作@content.save!不是一个好主意

更新

我尝试过:

def draft
    self[:draft]
end

def draft=(value)
    self[:draft] = value
end

def draft?
    self[:draft]
end

validates_presence_of :field1, :message => "msg1", :unless => :draft?
validates_presence_of :field2, :message => "msg2", :unless => :draft?
validates_presence_of :field3, :message => "msg3", :unless => :draft?

它有效,但我该如何对其进行分组?

unless self.draft?
    validates_presence_of :field1, :message => "msg1"
    validates_presence_of :field2, :message => "msg2"
    validates_presence_of :field3, :message => "msg3"
end

说的是草稿?没有找到方法。我也应该这样做

@article.content.draft = @article.draft

而且它看起来也像肮脏的黑客

I have model Article, for example. Article has_one ArticleContent. ArticleContent has validation of all it's attributes by default. But I need additional functionality - to save draft Article, without any validation.
So I pass :draft => false as one of a parameter in Article.new(), next I do @article.build_article_content(). There is some not working code in ArticleContent:

  def draft?
    raise self.article.draft
  end

  validates_presence_of :header, :message => "We have no fuckin' header!", :unless => :draft?

Of course it's not work. At the moment of draft? execution there is no any suitable Article object anywhere, so self.article returns nil. Nice try, codemonkey...

Anyone have some sweet ideas? I think to make @content.save! is not a very good idea

UPDATE

I tried so:

def draft
    self[:draft]
end

def draft=(value)
    self[:draft] = value
end

def draft?
    self[:draft]
end

validates_presence_of :field1, :message => "msg1", :unless => :draft?
validates_presence_of :field2, :message => "msg2", :unless => :draft?
validates_presence_of :field3, :message => "msg3", :unless => :draft?

It works, but how can I group this?

unless self.draft?
    validates_presence_of :field1, :message => "msg1"
    validates_presence_of :field2, :message => "msg2"
    validates_presence_of :field3, :message => "msg3"
end

Says that draft? method is not found. Also i should do

@article.content.draft = @article.draft

And it looks like dirty-dirty hack too

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

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

发布评论

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

评论(1

转瞬即逝 2024-10-19 06:06:01

这是状态机的常见用例。有几个 Rails 插件可以提供这些功能。

http://ruby-toolbox.com/categories/state_machines.html

如果您不这样做不需要完整的状态机实现,在您的 ArticleContent 模型中拥有一个状态列仍然具有指导意义。它的值可以是“新的”、“草稿”、“已发布”等。您的验证在决定要做什么时会查看该列的值,例如:(

validates :content, :presence => true, :unless => Proc.new { |a| a.state == "Draft" }

我很确定这不是正确的语法,但您应该得到我的目标。)

回答您的更新

尝试使用_options。

with_options :unless => :draft? do |o|
    o.validates_presence_of :field1, :message => "msg1"
    o.validates_presence_of :field2, :message => "msg2"
    o.validates_presence_of :field3, :message => "msg3"
end

看看你的代码,有一些味道。为了使验证失败,需要做的是 errors.add(blah),而不是引发异常。此外,您为访问草稿列定义的方法看起来有点多余。他们只是做 AR 会做的事情。

This is a common use case for a state machine. There are several rails plugins that provide for those.

http://ruby-toolbox.com/categories/state_machines.html

If you don't need a full state machine implementation it could still be instructive to have a state column in your ArticleContent model. Its values would be "new", "draft", "published" and so on. Your validations would look at that column's value when deciding what to do, like:

validates :content, :presence => true, :unless => Proc.new { |a| a.state == "Draft" }

(I'm pretty sure that's not the correct syntax but you should get what I'm aiming at.)

To answer your UPDATE

Try with_options.

with_options :unless => :draft? do |o|
    o.validates_presence_of :field1, :message => "msg1"
    o.validates_presence_of :field2, :message => "msg2"
    o.validates_presence_of :field3, :message => "msg3"
end

Looking at your code there's a couple of smells. In order to flunk a validation the thing to do is errors.add(blah), not raise an exception. Also, your methods defined for accessing the draft column look a little redundant. They're just doing what AR would do anyway.

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