Rails中嵌套表单的解决

来源:互联网 发布:淘宝网拖鞋批发 编辑:程序博客网 时间:2024/05/20 14:23

什么是嵌套表单呢?举个简单的例子吧,比如你有两个表,一个User表,另一个Account表,他们是一对一的关系(也可以一对多等)。现在需要提交一个表单的时候同时提交User,Account对应的字段数据。在Rails中有一种简单的方法解决,分别使用了这些方法

accepts_nested_attributes_for attr_accessiblefields_for

下面我们用代码进行说明一下。

class User < ActiveRecord::Base   has_one :account    accepts_nested_attributes_for :account  #注意添加这两行   attr_accessible  :account_attributesend
class Account<ActiveRecord::Basebelongs_to :user
class UsersController < ApplicationController  def new    @user = User.new    @user.account.build #不要遗漏  end def create     @user = User.new(params[:user])     if @user.save       ...              end  endend

users/new.html.erb:

 <% form_for @user do |f| %>    <%= f.text_field :name %>    <% f.fields_for :account do |pf| %> #注意这里      <%= pf.text_field :age %>    <% end %> <% end %>

这是一对一的情况,假设是一对多呢,如User has_many :accounts ; Account belongs_to :user这种情况下只要将对应的account改写成accounts,就ok了

一些深入参考:

http://robots.thoughtbot.com/post/52960938209/accepts-nested-attributes-for-with-has-many-through

http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

以上是Rails3中,如果在Rails4中使用了Using Strong Parameters ,参考这里

去掉model中的 attr_accessible :account_attributes ,在对应的controller中添加Strong Parameters的方法

http://www.railsexperiments.com/using-strong-parameters-with-nested-forms/


实例1:
coupon.rb中:
accepts_nested_attributes_for :cdkey, allow_destroy: true
作用是添加一对一cdkey表单的嵌套
_form.html.erb中:
div class="ui form">
  <%= form_for [:manage, @coupon], html: {multipart: true} do |f| %>


      <div class="fields">
        <div class="field">
          <%= f.label :coupon_type %>
          <%= f.select :coupon_type, Coupon::CouponType, {include_blank: "select coupon type"}, class: "ui dropdown" %>
        </div>


        <div class="field">
          <%= f.label :total_count, "数量限制" %>
          <%= f.text_field :total_count %>
        </div>
      </div>


      <div class="ui segment">


        <h4 class="ui header">CDKEY</h4>


        <div class="fields">
          <%= f.fields_for :cdkey do |c| %>
              <div class="field">
                <%= c.label :code, "cdkey 设置后可以输入该cdkey兑换优惠券"  %>
                <%= c.text_field :code %>
              </div>


              <div class="field">
                <%= c.label :count, "该cdkey可以兑换的次数"  %>
                <%= c.text_field :count %>
              </div>


              <div class="field">
                <%= c.label :start_at  %>
                <%= c.text_field :start_at, class: "datepicker" %>
              </div>


              <div class="field">
                <%= c.label :end_at  %>
                <%= c.text_field :end_at, class: "datepicker" %>
              </div>


              <div class="field">
                <label for="">Delete</label>
                <div class="ui checkbox">
                  <%= c.check_box :_destroy, style: "display: hidden" %>
                  <%= label_tag "删除"  %>
                </div>
              </div>
          <% end %>
        </div>


      </div>




      <div class="field">
        <%= f.label :name %>
        <%= f.text_field :name %>
      </div>


      <div class="field">
        <%= f.label :description %>
        <%= f.text_area :description, rows: 2 %>
      </div>


      <div class="fields">
        <div class="field">
          <%= f.label :start_time %>
          <%= f.text_field :start_time, class: "datepicker" %>
        </div>
        <div class="field">
          <%= f.label :end_time %>
          <%= f.text_field :end_time, class: "datepicker" %>
        </div>
      </div>


      <div class="fields">
        <div class="field">
          <%= f.label :active_days %>
          <%= f.text_field :active_days %>
        </div>
        <div class="field">
          <%= f.label :expiration_time %>
          <%= f.text_field :expiration_time, class: "datepicker" %>
        </div>
      </div>


      <div class="fields">
        <div class="field">
          <%= f.label :value %>
          <%= f.text_field :value %>
        </div>
        <div class="field">
          <%= f.label :status %>
          <%= f.select :status, Coupon::STATUS, {}, class: "ui dropdown" %>
        </div>
      </div>


      <div class="fields">
        <div class="field">
          <%= f.label :no_prefix %>
          <%= f.text_field :no_prefix %>
        </div>
      </div>


      <div class="ui segment">


        <h4 class="ui header">Can use countries</h4>


        <div class="ui grid">


          <div class="ui wide column">
            <div class="ui checkbox">
              <%= check_box_tag "coupon[countries_limit][]", "all", @coupon.countries_limit.to_a.include?("all"), style: "display: hidden" %>
              <%= label_tag "all" %>
            </div>
          </div>


          <% SupportCountry.all.each do |sc| %>
            <div class="ui wide column">
              <div class="ui checkbox">
                <%= check_box_tag "coupon[countries_limit][]", sc.iso_code, @coupon.countries_limit.to_a.include?(sc.iso_code), style: "display: hidden" %>
                <%= label_tag sc.iso_code  %>
              </div>
            </div>
          <% end %>
        </div>


      </div>


      <div class="field">
        <button class="ui submit blue button" type="submit" name="action">
          Submit
        </button>
      </div>


  <% end %>
</div>

注意:          <%= f.fields_for :cdkey do |c| %>
              <div class="field">
                <%= c.label :code, "cdkey 设置后可以输入该cdkey兑换优惠券"  %>
                <%= c.text_field :code %>
              </div>


              <div class="field">
                <%= c.label :count, "该cdkey可以兑换的次数"  %>
                <%= c.text_field :count %>
              </div>


              <div class="field">
                <%= c.label :start_at  %>
                <%= c.text_field :start_at, class: "datepicker" %>
              </div>


              <div class="field">
                <%= c.label :end_at  %>
                <%= c.text_field :end_at, class: "datepicker" %>
              </div>


              <div class="field">
                <label for="">Delete</label>
                <div class="ui checkbox">
                  <%= c.check_box :_destroy, style: "display: hidden" %>
                  <%= label_tag "删除"  %>
                </div>
              </div>
          <% end %>
这一段为对嵌套表单的提交
coupon_controller.rb中:
  def edit
    @coupon = Coupon.find(params[:id])
    if @coupon.cdkey.present?
      @cdkey  =@coupon.cdkey
    else
      @cdkey = @coupon.build_cdkey
    end
  end

  def update
    @coupon = Coupon.find(params[:id])
    if @coupon.update(coupon_params)
      redirect_to manage_coupons_path
    end
  end

  private
  def coupon_params
    params.require(:coupon).permit(
      :name, :coupon_type, :value, :description, :start_time, :end_time,
      :active_days, :expiration_time, :status, :no_prefix, :total_count, cdkey_attributes: [:id, :code, :start_at, :end_at, :count, :_destroy],
      countries_limit: []
    )
  end

注意:edit中的@cdkey = @coupon.build_cdkey这句和coupon_params健壮参数中 cdkey_attributes: [:id, :code, :start_at, :end_at, :count, :_destroy],这句
0 0
原创粉丝点击