1

用户有两个地址 shipping(:address_type=0) 和 billing(:address_type=1) 每次提交和验证失败时,都会生成每个地址类型的 2 个经典嵌套表单的用户表单。

楷模:

class User < ActiveRecord::Base
    has_many :addresses, :dependent => :destroy
    accepts_nested_attributes_for :addresses
    validates_associated :addresses
end

class Address < ActiveRecord::Base
    belongs_to :user  
    validates :user, :address_type, :first_name, :last_name, :street
end

控制器

class UsersController < ApplicationController

public
    def new
        @user = User.new
        @shipping_address = @user.addresses.build({:address_type => 0})
        @billing_address = @user.addresses.build({:address_type => 1})
    end

    def create
        @user = User.new(params[:user])
        if @user.save
            #fine
        else
            render => :new
        end
    end

不完整的表格

=form_for @user, :html => { :multipart => true } do |ff|
    =ff.fields_for :addresses, @shipping_address do |f|
        =f.hidden_field :address_type, :value => 0

    =ff.fields_for :addresses, @billing_address do |f|
        =f.hidden_field :address_type, :value => 1

    =ff.submit
4

2 回答 2

2

表格应如下所示:

=form_for @user, :html => { :multipart => true } do |ff|
    =ff.fields_for :addresses do |f|

没有其他的。Addressess 已经是一个集合,所以你应该只有一个渲染。此外,“:addresses, @shipping_address” 使得它可以呈现地址和送货地址,即使它包含在@user.addresses 中。

新操作中内置的地址将显示在那里,因为它们在地址集合中。

编辑

如果只需要这两个地址,可以排序后直接传给fields_for:

=form_for @user, :html => { :multipart => true } do |ff|
    =ff.fields_for ff.object.addresses.sort{|a,b| a.address_type <=> b.address_type } do |f|

那应该这样做。

于 2012-05-25T08:30:16.000 回答
0

惊讶吗?我想不是,但我是。我发现我说的对吗?它愚蠢而简单。

当验证失败并再次呈现新操作(表单)时,没有@shipping_address 也没有@billing_address。但是@user 已经构建了 2 个地址,并且嵌套表单的行为正确,可以在第一次验证失败时分别渲染两次。

    def create
        @user = User.new(params[:user])
        if @user.save
            #fine
        else
          @user.addresses.clear
          @user_address = @user.addresses.build({:address_type => 0})
          @user_address.attributes = params[:user][:addresses_attributes]["0"]

          @billing_address = @user.addresses.build({:address_type => 1})
          @billing_address.attributes = params[:user][:addresses_attributes]["1"]
          render => :new
        end
    end
于 2012-05-24T22:06:30.510 回答