2011-02-05 46 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