巢为属性的has_many如果表单验证失败不显示 [英] nester attributes for has_many are not shown if the form fails validation

查看:194
本文介绍了巢为属性的has_many如果表单验证失败不显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果表单验证失败,为的has_many关联领域,从视野中消失:

我的新动作看起来像

 高清新
  @realty = Realty.new
  @ realty.build_user
  @ realty.build_address
  #用户,地址是HAS_ONE协会,和他们留在视图后,未通过验证
  6.times {@ realty.realty_images.build}#,这一次客场消失
  做的respond_to |格式|
    format.html#new.html.erb
    format.json {渲染JSON:@realty}
  结束
结束

如果我将添加到我的表单这个片段

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

字段再次显示了起来,但它是一个有点粗糙

我试过

  6.times {@ realty.realty_images.build}如果@ realty.realty_images.empty?

  6.times {@ realty.realty_images.build}
6.times {@ realty.realty_images.build}如果@ realty.realty_images.empty?

在控制器上,但它没有工作,和字段验证失败再次消失了。

创建操作:

  DEF创建
    @realty = Realty.new(PARAMS [:不动产])
    做的respond_to |格式|
      如果@ realty.save
        format.html {redirect_to的@realty,通知:地产已成功创建。 }
        format.json {渲染JSON:@realty,状态:创建,地点:@realty}
      其他
        format.html {渲染动作:新}
        format.json {渲染JSON:@ realty.errors,状态:unprocessable_entity}
      结束
    结束
 结束

我的构型

  = simple_form_for(@realty)做| F |
  = f.error_notification  .FORM-输入
    = f.input:OFFER_TYPE
    = f.input:realty_type
    = f.input:rent_type
    = f.input:价格
    = f.input:说明
    = f.input:状态,如:隐藏
    = f.input:number_of_rooms
    = f.input:地板
    = f.input:服务,如:隐藏
    = f.simple_fields_for:地址做| address_f |
      = address_f.input:城市:需要=>真正
      = address_f.input:状态:需要=>真正
      = address_f.input:街道:所需=>真正
     - 除非user_signed_in?
      = f.simple_fields_for:用户做| user_f |
        = user_f.input:姓名,:自动对焦=>真的,:需=>真正
        = user_f.input:电话:所需=>真正
        = user_f.input:电子邮件:所需=>真正
        = user_f.input:密码:所需=>真正
        = user_f.input:password_confirmation,:需=>真正
     - 如果@ realty.realty_images.empty?
       - 6.times {@ realty.realty_images.build}
    = f.simple_fields_for:realty_images做| image_f |
      = image_f.input:形象,为:文件  .FORM-行动
    = f.button:提交

地产模型

 类不动产LT; ActiveRecord的::基地
  attr_accessible:描述:楼:USER_ID,:number_of_rooms,:价格:服务:状态:realty_images_attributes,:address_attributes,:user_attributes,:OFFER_TYPE,:realty_type,:rent_type  belongs_to的:用户:依赖=> :销毁:CLASS_NAME => 用户
  的has_many:realty_images,:依赖=> :破坏
  HAS_ONE:地址:依赖=> :破坏  验证:OFFER_TYPE,:presence =>真的,:长度=> {:在= GT; 1..25​​6}
  验证:realty_type,:presence =>真的,:长度=> {:在= GT; 1..25​​6}
  验证:状态:presence =>真的,:长度=> {:在= GT; 1..25​​6}
  验证:描述:长度=> {:最大=> 2000}
  验证:服务:presence =>真的,:长度=> {:在= GT; 1..25​​6}
  accepts_nested_attributes_for:realty_images
  accepts_nested_attributes_for:用户
  accepts_nested_attributes_for:地址
结束


解决方案

我想你混淆了两个动作:新的创造。在/不动产/新访问的空白表单只有当新的动作被调用。并提交表单时,创造的动作被调用。

您只能在新行动增加6个样品的图像。在创建行动, Realty.new 将放弃为空的(未填写)图像。这就是为什么你会看到他们消失。您将需要重新添加他们在验证错误。你可以提取常用的设置成一个方法:

 类RealtiesController
  高清新
    @realty = Realty.new
    @ realty.populate
  结束  打造高清
    @realty = Realty.new(PARAMS [:不动产])
    如果@ realty.save
      #...
    其他
      @ realty.populate
      使新
    结束
  结束
结束房地产类
  #你也可以将它放在控制器
  #如果你觉得它适合有更好
  DEF填充
    6.times {} self.realty_images.build
  结束
结束

If form fails validation, fields for has_many association, disappears from view:

my new action looks like

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 I add to my form this snippet

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

fields are shown up again, but it is a little rough

I tried

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

or

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

in controller, but it doesn't works, and fields disappears again on failed validation.

create action:

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

my -form

= 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

realty model

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

解决方案

I think you are confusing two actions: new and create. The "new" action is invoked only when accessing the blank form at /realties/new. And the "create" action is invoked when submitting the form.

You add 6 sample images only in "new" action. In create action, Realty.new will discard images that are blank (not filled in). This is why you will see them disappear. You will need to re-add them on validation error. You could extract the common setup into a method:

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

这篇关于巢为属性的has_many如果表单验证失败不显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆