2014-10-28 65 views
1

我有一個MediaItem模型有兩個has_one關聯。我驗證了一個或另一個存在使用:爲什麼這些錯誤呈現爲嵌套關聯?

validates_presence_of :photo, allow_nil: true 
validates_presence_of :video, allow_nil: true 
validate :photo_or_video_present 

def photo_or_video_present 
    if !(photo.blank?^video.blank?) 
    errors['photo_attributes.image'] << 'Select a photo or a video' 
    errors['video_attributes.uid'] << 'Select a photo or a video' 
    end 
end 

這給了我當的形式呈現以下錯誤對象:

<ActiveModel::Errors:0x007f99c8a71fc0 
    @base=#<MediaItem id: nil, 
        title: "asdadasdasd", 
        slug: "asdadasdasd", 
       gallery_id: 1, 
       created_at: nil, 
       updated_at: nil>, 
    @messages={:"photo_attributes.image"=>["Select a photo or a video"],   
       :"video_attributes.uid"=>["Select a photo or a video"], 
       :title=>[] }> 

然而,這些錯誤不會在嵌套模型顯示。該形式如下:

<div class="FormWrapper"> 
    <%= simple_form_for [:admin, @gallery, @media_item], html: { class: "#{action_name.titleize}PhotoForm" } do |f| %> 
    <%= f.input :title %> 


    <div class="PhotoInputs"> 
     <h3>Photo</h3> 
     <%= f.simple_fields_for :photo do |ff| %> 
     <%= ff.input :image, as: :file_upload, input_html: {preview: @media_item.photo.image} %> 
     <% end %> 
    </div> 

    <div class="VideoInputs"> 
     <h3>Video</h3> 
     <%= f.simple_fields_for :video do |ff| %> 
     <%= ff.input :provider, as: :radio_buttons, collection: Video::PROVIDERS %> 
     <%= ff.input :uid %> 
     <% end %> 
    </div> 

    <hr> 
    <%= render partial: 'shared/form_submit', locals: {resource: @media_item} %> 
    <% end %> 
</div> 

爲什麼這些內嵌錯誤無法顯示?

注意:表單的功能沒有絕對的問題。我可以創建和編輯模型和嵌套模型都沒有問題。

回答

1

這2個驗證什麼都不做validates_presence_of :photo, allow_nil: truevalidates_presence_of :video, allow_nil: true因爲您正在驗證存在但允許它不存在。我只是將error添加到:base並在視圖中渲染。例如

validates :has_photo_or_video 

def has_photo_or_video 
    if (photo.blank?^video.blank?) 
    errors.add(:base,"Please select a photo or video") 
    end 
end 

然後在視圖

<% f.errors[:base].each do |message| %> 
    <span>message</span> 
<% end %> 

像你描述的雖然你可以嘗試這樣的事情,以及我還沒有看到內嵌錯誤的實現:

def has_photo_or_video 
    if !(photo.blank?^video.blank?) 
    photo.errors.add(:image,"Please select a photo or video") 
    video.errors.add(:uid,"Please select a photo or video") 
    end 
end 

雖然我做沒有關於這是否可行的說明。

你的問題是,它正在尋找被包含在一個嵌套的哈希你的錯誤,像

{photo_attributes: {image: ["Please select a photo or video"]}, 
video_attributes: {uid: ["Please select a photo or video"]} } 

我已經看到這種情況的唯一途徑是通過驗證的相關模型,這是不可能的你因爲它是一種或兩種類型的程序。至少據我瞭解。

如果這是一個非此即彼的類型的程序意義的MediaItem要麼是Photo一個Video不能同時那麼我會建議尋找到多態性,因爲它會使這個過程更容易。

或者甚至更好的還是報廢MediaItem一起和title屬性添加到PhotoVideo然後分別創建一個,因爲這似乎是最簡單的途徑。 (您仍然可以爲media_items定義一種方法,以獲取所有這些方法)

+0

謝謝。我已經爲這個例子大大簡化了MediaItem。它具有許多其他功能,可以在視頻和照片中共享,並以多態性作爲糟糕選擇的方式與其他模型綁定。就內聯錯誤而言,簡單形式給我提供了與這些屬性相關的所有MediaItem錯誤的開箱即用錯誤,所以當你說你沒有看到內聯錯誤的實現時,我描述的是你特別的談論嵌套模型的內聯錯誤? – Undistraction 2014-10-29 07:23:45

+1

@Pedr是的我已經看到這樣的內聯錯誤實現,但只有當驗證是在嵌套模型而不是父對象上執行時。由於您的設計無法對嵌套模型執行驗證,因此我不確定解決基本錯誤的最佳方法。 – engineersmnky 2014-10-29 12:44:48

相關問題