【问题标题】:Rails / nested attributes / file_field doesn't show up within params when emptyRails / 嵌套属性 / file_field 为空时不显示在 params 中
【发布时间】:2011-06-22 01:41:17
【问题描述】:

我有两个模型,第一个模型 (model_1) 接受第二个模型 (model_2) 的嵌套属性。第二个模型只有一个字段(file),在表单中作为文件字段引用。

没有选择文件时出现问题。在这种情况下——除了一个文本字段——该字段根本不会出现在 POST 参数中,第一个模型认为根本不应该创建任何嵌套模型。哪个无法触发验证等。如果我要向 model_2 和相应的表单添加第二个字段,并且如果我使用的是文本输入,那么一切都会顺利进行,并且文件字段的验证自然也可以正常工作。

有没有人知道如何解决这个问题?

为了更好地使用一些(简化的)代码——形式:

= form_for @model_1, :html => { :multipart => true } do |f|
    - # fields for model 1 …
    = f.fields_for :model_2 do |builder|
        - # if this is empty, it's like no model_2 would be created at all:
        = builder.file_field :file

模型 1:

class Model1 < ActiveRecord::Base
    has_many :model_2s, :dependent => :destroy
    accepts_nested_attributes_for :model_2s
    # …
end

和模型 2:

class Model2 < ActiveRecord::Base
    belongs_to :model_1
    validates_presence:of :file
    # …
end

【问题讨论】:

  • 如果在创建表单之前在控制器中创建链接到 model1 的 model2 会怎样?这样,model2 的更新就不能忽略验证了?
  • 我实际上是这样做的@model_2 = @model_1.model_2s.build。不过,似乎没有任何改变。
  • 您应该添加 .save(false) 以真正保存对象并在此处绕过验证
  • 但是我不会得到很多这样的无效条目吗?
  • 发现这个:stackoverflow.com/questions/3152001/… 但与隐藏属性相比似乎有点过分了

标签: ruby-on-rails validation nested-attributes filefield


【解决方案1】:

如果文件字段丢失,我建议在控制器中添加检查并返回 flash[:error] 消息。

如果字段不存在,您也可以手动添加,以便触发验证:

m1params = 参数[:model_1] m1params[:model_2_attributes] = {} 除非 m1params.has_key?(:model_2_attributes)

最后,您可以在您的 model_2 模型中创建一个假属性,您可以使用它来确保 model_2_attributes 以以下形式传递:

类模型2 attr_writer :假的 假的 @fake ||= '默认' 结尾 结尾 = form_for @model_1, :html => { :multipart => true } 做 |f| - # 模型 1 的字段… = f.fields_for :model_2 做 |builder| = builder.hidden_​​field :fake = builder.file_field:文件

【讨论】:

  • 感谢您的回答。我也一直在考虑使用隐藏的输入字段,但是所有这些解决方案在某种程度上都感觉不到 100% right — 如果你明白我的意思,这有点老套?我仍然希望通过 Rails 找到解决方案……
  • 您还可以向 Model1 添加验证,以确保它至少有一个与之相关的 Model2 - 如果 Model2 不存在,这将导致另一个验证失败。
  • +1 这似乎是迄今为止最好的解决方案。我会再考虑一下,然后再回来。
  • 我添加了一个hidden_field :force_validation 并为模型添加了一个访问器。这有效(因此接受了答案),但仍然困扰着我。也许我会在重构回合中找到更好的解决方案。验证仍然是一个开放的建议,目前不适合我的设计。干杯!
【解决方案2】:

最后,这似乎是答案:

https://github.com/perfectline/validates_existence

这是一个示例:

class Unicorn < ActiveRecord::Base
  belongs_to :wizard
  belongs_to :person, :polymorphic => true

  validates :wizard,    :existence => true
  validates :wizard_id, :existence => true # works both way
  validates :person,    :existence => { :allow_nil => true, :both => false }
end

【讨论】:

  • 谢谢,看起来很有趣。但这不适用于关系的has_many 方面,我怎么看?这种类型的验证已经讨论过几次(请参阅 apneadiving 的评论或stackoverflow.com/questions/4309354/…),但我目前仍在努力解决文件字段根本不显示而不是空的简单限制(如复选框,如果你会)在这种特殊情况下以及我所做的一些设计选择。我会回来的。
猜你喜欢
  • 1970-01-01
  • 2018-11-19
  • 1970-01-01
  • 1970-01-01
  • 2021-01-13
  • 1970-01-01
  • 1970-01-01
  • 2015-08-16
  • 2014-03-22
相关资源
最近更新 更多