如何在将关联表属性保存在 Ruby on Rails 中之前在验证中访问它们

发布于 2024-11-10 17:29:37 字数 1577 浏览 3 评论 0原文

我希望如果某个属性设置为 false(例如状态),则能够跳过验证,问题是该模型有许多嵌套属性,如果状态为 false,它们也需要跳过验证。

这种植入的目的是,如果有人想要保存表单条目的草稿,无论出于何种原因,对其进行验证可能会阻止他们保存它,这是不可取的行为,并且只需要验证即将公开的条目通过将状态设置为 true。

下面的示例

位于文章

model Article
  has_many :sub_articles
  accepts_nested_attributes_for :sub_articles, :allow_destroy => true

  validate_presence_of :body, :unless => Proc.new{|article| !article.status }

model SubArticle
  belongs_to :article
  has_many :foos
  accepts_nested_attributes_for :foos, :allow_destroy => true    

  validate_presence_of :body, :unless => Proc.new{|sub_article| !sub_article.article.status }

model Foo
  belongs_to :sub_article

  validate_presence_of :body, :unless => Proc.new{|foo| !foo.sub_article.article.status }

验证中,跳过 Article 的属性状态可以工作,但对于 SubArticle 或 Foo 则不起作用,因为它们尚未保存且未设置 id,无法使它们能够像示例中那样遍历关联。

是否可以在验证时访问关联的表属性?

任何帮助将不胜感激。

------更新------

SubArticle 和 Foo 验证失败的原因是由于

未定义方法“状态” nil:NilClass

这是预期的,因为验证时,article_id 或 sub_article_id 仍然是 nil,我已经通过做

model SubArticle
  belongs_to :article
  has_many :foos

  validate_presence_of :body, :unless => Proc.new{|sub_article| !sub_article.article.check_attributes }

def check_attributes
  pp self
end

女巫给出

#<SubArticle id: nil, body: "", article_id: nil, created_at: nil, updated_at: nil >

-----updated 2----------

确认了这一点,我忘记了,很重要详细地说,模型的所有数据都是使用嵌套形式一次性输入的,因此在创建时,所有模型上的所有条目仅在内存中,固定示例代码,以便更加明显。

I want to be able to skip validation if a certain attribute is set to false, say status, problem is this model has many nested attributes to them, and they need to skip validation too if status is false.

The purpose of such implantation is that if one wanted to save a draft of there form entry, for whatever reason, having it going through validation could halt them saving it, which is not desirable behavior, and only need to validate entries that are going public by setting status to true.

Example below

attribute status located in Article

model Article
  has_many :sub_articles
  accepts_nested_attributes_for :sub_articles, :allow_destroy => true

  validate_presence_of :body, :unless => Proc.new{|article| !article.status }

model SubArticle
  belongs_to :article
  has_many :foos
  accepts_nested_attributes_for :foos, :allow_destroy => true    

  validate_presence_of :body, :unless => Proc.new{|sub_article| !sub_article.article.status }

model Foo
  belongs_to :sub_article

  validate_presence_of :body, :unless => Proc.new{|foo| !foo.sub_article.article.status }

validation skipping for Article will work, but will not for SubArticle or Foo since they have not been saved an there ids are not set, not making them able to traverse up the associations like in the example.

Is it possible to access associated table attributes at the point of validation?

Any help would be greatly appreciated.

------Updated------

The reason validation for SubArticle and Foo fail is because of a

undefined method `status' for
nil:NilClass

This is expected because of the time of validation the article_id or sub_article_id is still nil, I've comfirmed this by doing

model SubArticle
  belongs_to :article
  has_many :foos

  validate_presence_of :body, :unless => Proc.new{|sub_article| !sub_article.article.check_attributes }

def check_attributes
  pp self
end

witch gives

#<SubArticle id: nil, body: "", article_id: nil, created_at: nil, updated_at: nil >

-----updated 2----------

I forgot and important detail, all of the data for the models are entered at once using a nested form, so at the moment of create, all of the entries on all of the models are only in memory, fixing example code so that would be more obvious.

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

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

发布评论

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

评论(3

懵少女 2024-11-17 17:29:37

这是可能的,但您需要使用 => 而不是 =。像这样:

validate_presence_of :body, :unless => Proc.new{|article| !article.status }

请查看:http://guides.rubyonrails.org/active_record_validations_callbacks.html#有关条件验证的更多信息,请参阅条件验证

It is possible but you need to use => instead of =. Like this:

validate_presence_of :body, :unless => Proc.new{|article| !article.status }

Please look at: http://guides.rubyonrails.org/active_record_validations_callbacks.html#conditional-validation for more information about conditional validations.

帅气称霸 2024-11-17 17:29:37

对 ID 进行条件验证怎么样?

model Article
  has_many :sub_articles

  validate_presence_of :body, :unless => Proc.new{|article| !article.status }

    model SubArticle
      belongs_to :article
      has_many :foos

      validate_presence_of :body, :unless => Proc.new{|sub_article| !sub_article.article_id}

model Foo
  belongs_to :sub_article

  validate_presence_of :body, :unless => Proc.new{|foo| !foo.sub_article_id }

不确定这是否有效,但您基本上只在父模型已保存并因此具有 ID 的情况下才运行验证。但不适用于更新。也许将此代码与您的原始代码混合起来可以进行更新?

What about conditionally validating on the ID?

model Article
  has_many :sub_articles

  validate_presence_of :body, :unless => Proc.new{|article| !article.status }

    model SubArticle
      belongs_to :article
      has_many :foos

      validate_presence_of :body, :unless => Proc.new{|sub_article| !sub_article.article_id}

model Foo
  belongs_to :sub_article

  validate_presence_of :body, :unless => Proc.new{|foo| !foo.sub_article_id }

Not sure if this will work but you're essentially only running validation if the parent model has saved and therefore has an ID. Won't work for updates though. Perhaps a mix between this and your original code would do for update?

旧时浪漫 2024-11-17 17:29:37

我已经让它工作了,虽然有点黑客风格,但通过使用 :inverse_of 解决了无法遍历关联的问题,因为 id 为零,

model Article
  has_many :sub_articles, :inverse_of => :article

  validate_presence_of :body, :unless => Proc.new{|article| !article.status }

model SubArticle
  belongs_to :article, :inverse_of => :sub_articles
  has_many :foos, :inverse_of => :foo

  validate_presence_of :body, :unless => Proc.new{|sub_article| !sub_article.article.status }

model Foo
  belongs_to :sub_article, :inverse_of => :foos

  validate_presence_of :body, :unless => Proc.new{|foo| !foo.sub_article.article.status }

这将使所有层中正在检查的实例都可以访问状态属性。

I've got it working, although hack-ish, solved the can't traverse associations since ids are nil by using the :inverse_of

model Article
  has_many :sub_articles, :inverse_of => :article

  validate_presence_of :body, :unless => Proc.new{|article| !article.status }

model SubArticle
  belongs_to :article, :inverse_of => :sub_articles
  has_many :foos, :inverse_of => :foo

  validate_presence_of :body, :unless => Proc.new{|sub_article| !sub_article.article.status }

model Foo
  belongs_to :sub_article, :inverse_of => :foos

  validate_presence_of :body, :unless => Proc.new{|foo| !foo.sub_article.article.status }

Which will make the instance being examined in all layers have access to the status attribute.

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