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
4

3 に答える 3

1

失敗したオブジェクトを #new に引き続き存在させるには、古いオブジェクトが存在する場合に新しいオブジェクトを作成しないようにすることができます。このような:

@realty = || Realty.new

このように #new は、新しいオブジェクトの代わりに古い失敗したオブジェクトを使用します。

@realty オブジェクトの場合は機能します。ただし、ユーザーとアドレスなどのさらなる関連付けについては、以前に同様のことを行ったことがないため、自分で確認する必要があります.

ps コードはインスタント変数に依存しているため、obj の保存方法が気になります。これが少し役立つことを願っています:)

于 2013-05-07T09:16:15.983 に答える
1

new と create という 2 つのアクションを混同していると思います。「新規」アクションは、/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
于 2013-05-08T10:09:17.990 に答える
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
于 2013-05-07T10:45:33.253 に答える