【问题标题】:Rails 4 nested form not loading values on show/editRails 4嵌套表单未在显示/编辑时加载值
【发布时间】:2015-08-03 03:39:19
【问题描述】:

我有一个订单表格,其中包含产品的嵌套表格。产品正确保存到数据库,但在显示/编辑产品值时未加载 - 字段显示但未填充。

订购型号:

has_many :products, dependent: :destroy
accepts_nested_attributes_for :products

产品型号:

belongs_to :order

orders_controller:

before_action :set_order, only: [:show, :edit]

def new
  @order = Order.new
  @order.products.build
end

def show
  # empty
end

def edit
  # empty
end

def order_params
  params.require(:order).permit(
    :number,
    :price,
    products_attributes: [
      :id,
      :type,
      :color
    ])
end

def set_order
  if params[:id].present? && user_signed_in?
    @order = Order.find(params[:id])
  elsif params[:number].present? && params[:email].present?
    @order = Order.find_by(number: params[:number], email: params[:email])
  else
    redirect_to welcome_index_path, alert: I18n.t('views.welcome.index.no_order_found')
  end
end

routes.rb:

resources :orders do
  get 'express', on: :new
end
post 'orders/status', to: 'orders#show'

_form.html.erb(编辑和显示都使用):

<%= form_for @order do |f| %>
  <%= f.text_field(:number) %>
  # etc.
  <%= f.fields_for :products do |g| %>
    <%= g.text_field(:color) %>
    # etc.
  <% end %>
<% end %>

【问题讨论】:

  • 这里只是猜测,但由于has_many,它可能无法显示。如果有很多产品,它怎么知道显示哪个产品的颜色?
  • 你能贴出显示/编辑的代码吗?
  • 能否请您从 routes.rb 发布相关部分?您是否尝试将产品分配给变量并将 f.fields_for :products,@your_assigned_variable_for_products 做 || ?
  • @Vasseurth 我正在关注here 的示例。我也有同样的想法,所以就像@DeOldSax 说的我尝试在 show 中分配一个变量(@product = @order.products.last - 我现在只关心一个产品)并将其传递给 fields_for 但它没有任何区别

标签: ruby-on-rails


【解决方案1】:

您的代码看起来不错,应该可以工作。您能否尝试以下更改以在表单字段中传递@products

<%= f.fields_for :products, @products do |g| %>
   <%= g.text_field(:color) %>
   # etc.
<% end %>

只需让@products 变量在newedit 操作中可用。喜欢关注

def new
  #your code goes here ...
  @products = @order.products.build
end


def edit
  #your code goes here ...
  @products = @order.products
end

【讨论】:

    【解决方案2】:

    我终于找到了问题所在——它在我的自定义 FormBuilder 类中。我没有将它包含在原始问题中,因为我认为它不相关。我的表单实际上看起来更像这样:

    <%= f.fields_for :products, builder: MyFormBuilder do |g| %>
      <%= g.product_select(:color) %>
      <%= g.product_checkbox(:accessories) %>
      # etc.
    <% end %>
    

    MyFormBuilder 有以下方法:

    def product_select(label)        
      tags = ''
      Product.send(label.to_s.pluralize).each do |a|
        tags += @template.content_tag(:option, a[:text], value: a[:value], data: a[:data])
      end
      tag_with_label(label) do
        @template.select(@object_name, label, nil, {}, options) { tags.html_safe }
      end
    end
    
    def product_checkbox(label)
      tag_with_label("#{label.to_s}?") do
        @template.check_box(@object_name, label)
      end
    end
    

    问题是没有指定如何为现有对象加载保存的属性。以下是这些方法的固定版本:

    def product_select(label)
      choices = @template.options_for_select(Product.send(label.to_s.pluralize), @object.send(label))
      tag_with_label(label) do
        @template.select(@object_name, label, choices, {}, options)
      end
    end
    
    def product_checkbox(label)
      tag_with_label("#{label.to_s}?") do
        @template.check_box_tag("#{@object_name}[#{label}]", 1, @object.send(label)) 
      end
    end
    

    关键部分是@object.send(label),这是一个从数据库中检索适当属性的方法调用。我还更改了 Product 模型以返回 options_for_select 预期格式的数组(数组数组)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-15
      • 1970-01-01
      相关资源
      最近更新 更多