2011-02-05 48 views
3

我有两个模型,第一个(model_1)接受第二个嵌套属性(model_2)。第二个模型只有一个字段(file),它在表单中作为文件字段引用。当空时,Rails /嵌套属性/ file_field不会在params内显示

问题出在没有选择文件。在这种情况下(除了说文本字段),字段在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 
+0

如果你创建创建窗体之前链接在你的控制器MODEL1的MODEL2?这样,model2的更新不能忽略验证否? – apneadiving 2011-02-05 23:09:59

+0

我正在这样做`@ model_2 = @ model_1.model_2s.build`。虽然似乎没有改变任何东西。 – polarblau 2011-02-05 23:28:02

+0

您应该添加.save(false)来真正保存对象并在此绕过验证 – apneadiving 2011-02-05 23:32:16

回答

1

我建议增加一个检查在您的控制器中,并且如果文件字段丢失,则返回闪烁[:错误]消息。

您也可以手动添加字段,如果它们不存在,因此验证被触发:

 
m1params = params[:model_1] 
m1params[:model_2_attributes] = {} unless m1params.has_key?(:model_2_attributes) 

最后,你可以在你的model_2示范创建一个假attribue,你可以用它来保证model_2_attributes获得在形式传递:

 
class Model2 
    attr_writer :fake 

    def fake 
    @fake ||= 'default' 
    end 
end 

= form_for @model_1, :html => { :multipart => true } do |f| 
    - # fields for model 1 … 
    = f.fields_for :model_2 do |builder| 
     = builder.hidden_field :fake 
     = builder.file_field :file 
0

最后,这似乎回答:

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