2013-05-07 63 views
0
沒有顯示

如果表單驗證失敗,爲的has_many關聯領域,從視野中消失:巢老人的屬性,如果表單驗證失敗

我的新動作看起來像

def new 
    @realty = Realty.new 
    @realty.build_user 
    @realty.build_address 
    #user, address are has_one association, and they stay in view after failed validation 
    6.times { @realty.realty_images.build } # and this one vanishes away 
    respond_to do |format| 
    format.html # new.html.erb 
    format.json { render json: @realty } 
    end 
end 

如果我添加到我的形成這個片段

- if @realty.realty_images.empty? 
    - 6.times { @realty.realty_images.build } 

領域會再次顯示,但它是一個有點粗糙

我試圖

6.times { @realty.realty_images.build } if @realty.realty_images.empty? 

6.times { @realty.realty_images.build } 
6.times { @realty.realty_images.build } if @realty.realty_images.empty? 
在控制器

,但它沒有工作,和田野上驗證失敗再次消失。

創建行動:

def create 
    @realty = Realty.new(params[:realty]) 
    respond_to do |format| 
     if @realty.save 
     format.html { redirect_to @realty, notice: 'Realty was successfully created.' } 
     format.json { render json: @realty, status: :created, location: @realty } 
     else 
     format.html { render action: "new" } 
     format.json { render json: @realty.errors, status: :unprocessable_entity } 
     end 
    end 
end 

我 - 體

= simple_form_for(@realty) do |f| 
    = f.error_notification 

    .form-inputs 
    = f.input :offer_type 
    = f.input :realty_type 
    = f.input :rent_type 
    = f.input :price 
    = f.input :description 
    = f.input :state, as: :hidden 
    = f.input :number_of_rooms 
    = f.input :floor 
    = f.input :service, as: :hidden 
    = f.simple_fields_for :address do |address_f| 
     = address_f.input :city, :required => true 
     = address_f.input :state, :required => true 
     = address_f.input :street, :required => true 
    - unless user_signed_in? 
     = f.simple_fields_for :user do |user_f| 
     = user_f.input :name, :autofocus => true, :required => true 
     = user_f.input :phone, :required => true 
     = user_f.input :email, :required => true 
     = user_f.input :password, :required => true 
     = user_f.input :password_confirmation, :required => true 
    - if @realty.realty_images.empty? 
     - 6.times { @realty.realty_images.build } 
    = f.simple_fields_for :realty_images do |image_f| 
     = image_f.input :image, as: :file 

    .form-actions 
    = f.button :submit 

房地產模型

class Realty < ActiveRecord::Base 
    attr_accessible :description, :floor, :user_id, :number_of_rooms, :price, :service, :state, :realty_images_attributes, :address_attributes, :user_attributes, :offer_type, :realty_type, :rent_type 

    belongs_to :user, :dependent => :destroy, :class_name => "User" 
    has_many :realty_images, :dependent => :destroy 
    has_one :address, :dependent => :destroy 

    validates :offer_type, :presence => true, :length => { :in => 1..256 } 
    validates :realty_type, :presence => true, :length => { :in => 1..256 } 
    validates :state, :presence => true, :length => { :in => 1..256 } 
    validates :description, :length => { :maximum => 2000 } 
    validates :service, :presence => true, :length => { :in => 1..256 } 
    accepts_nested_attributes_for :realty_images 
    accepts_nested_attributes_for :user 
    accepts_nested_attributes_for :address 
end 
+0

請顯示#create,這是關鍵。 – 2013-05-07 07:19:04

+0

我把它添加到我的問題。但它是相當標準:) – 2013-05-07 07:26:44

+0

似乎不好。你沒有邏輯來保存創建的用戶,地址和圖像? – 2013-05-07 07:35:45

回答

1

我認爲你混淆了兩個動作:新建和創建。只有在/ realties/new中訪問空白表單時纔會調用「新」操作。提交表單時會調用「創建」操作。

您只在「新」操作中添加6個樣本圖像。在創建動作中,Realty.new將丟棄空白圖像(未填充)。這就是爲什麼你會看到它們消失。您需要在驗證錯誤時重新添加它們。您可以將通用設置提取到方法中:

class RealtiesController 
    def new 
    @realty = Realty.new 
    @realty.populate 
    end 

    def create 
    @realty = Realty.new(params[:realty]) 
    if @realty.save 
     # ... 
    else 
     @realty.populate 
     render 'new' 
    end 
    end 
end 

class Realty 
    # you could also place it in the controller 
    # if you feel it fits better there 
    def populate 
    6.times{ self.realty_images.build } 
    end 
end 
+0

它通常是相同的,但更優雅的方法。這個工程,但驗證有關realty_images表單字段的錯誤,不顯示:( – 2013-05-08 10:16:48

+0

是的,他們是從主要模型(房地產)分開。你必須得到並顯示每個人的realty_image.errors。 – 2013-05-09 05:03:24

1

爲了讓失敗的對象仍然存在於#NEW,你可以避開創建如果舊的存在,則爲新的。像這樣:

@realty = || Realty.new 

這樣#new將使用舊的失敗對象而不是新的。

對於@realty對象,它將起作用。但對於進一步的關聯,如用戶和地址,我以前沒有做過類似的事情,所以你需要自己驗證它。

p.s代碼依賴於即時變量,這就是爲什麼我關心如何保存obj。希望這可以有一點幫助:)

+0

你的意思是@realty || = Realty.new?這並不能解決問題。我只接受了accepted_nested_attributes_for:realty_images字段的問題,它們在驗證失敗後消失,所有其他字段都停留在那裏。感謝您的幫助。我已經部署應用程序到我的VPS,你可以看看這裏http://www.andryas.info – 2013-05-07 09:32:15

+0

@AndreyYasinishyn,我沒有類似的情況。但我認爲解決方案是使用圖像的實例來構建表單,如果#create失敗,則保留此實例不變並交付給#new。 – 2013-05-07 09:39:05

+0

你是什麼意思?如何實現這一點? – 2013-05-07 09:40:37

0

@Billy Chan謝謝你的建議,你真的幫助我。我的這個問題的解決方案,是有點粗糙,但它工作得很好

在創建行動增加

6.times { @realty.realty_images.build } if @realty.realty_images.empty? 

如果@ realty.save返回false

它看起來像這樣

def create 
    @realty = Realty.new(params[:realty]) 
    @realty.user = current_user if user_signed_in? 
    respond_to do |format| 
     if @realty.save 
     format.html { redirect_to @realty, notice: 'Realty was successfully created.' } 
     format.json { render json: @realty, status: :created, location: @realty } 
     else 
     6.times { @realty.realty_images.build } if @realty.realty_images.empty? 
     format.html { render action: "new" } 
     format.json { render json: @realty.errors, status: :unprocessable_entity } 
     end 
    end 
    end