Accepts_nested_attributes_for 和二阶关联、嵌套形式

发布于 2024-10-31 17:15:01 字数 1708 浏览 1 评论 0原文

我有以下具有关联的模型:

class Order < ActiveRecord::Base
  has_many :guests
  has_many :customers, :through => :guests
  accepts_nested_attributes_for :customers
end

class Customer < ActiveRecord::Base
   has_many :guests
   has_many :orders, :through => :guests
   has_many :slips
   accepts_nested_attributes_for :slips
end

class Slip < ActiveRecord::Base
   belongs_to :order
   belongs_to :customer
end

class Guest < ActiveRecord::Base
  belongs_to :order
  belongs_to :customer
end

我的嵌套表单如下所示:

<!-- general form -->
<%= form_for(@order) do |f| %>
    <% f.fields_for :customers do |builder| %>
        <%= render "customer_fields", :f => builder %>
    <% end %>
    <%= f.submit %>
<% end %>

<!-- partial customer_fields -->
<p>
    <%= f.label :name%><%= f.text_field :name %>
    <% f.fields_for :slips do |builder| %>
        <%= render "slip_fields", :f => builder %>
    <% end %>
</p>

<!-- partial slip_fields -->
<p><%= f.label :quantity%><%= f.text_field :quantity %></p>

通过此设置,保存订单可以按预期工作,但我需要将 order_id 与单据一起保存,因此我在订单 <-> 之间有一个引用。滑。通过这种设置,我失去了参考。我可以获取所有关联的客户,但我将获取与订单相关或不相关的客户的所有关联单据。


这是我的模型的字段: 订单->编号
客户->编号
访客-> id、order_id、customer_id
滑倒-> id, order_id, customer_id


订单的结果应如下所示

  • Order
    1. 客户 A
      • 单据 1
      • 单据 2
    2. 客户 B
      • 单据 1
      • 单据 2
    3. 客户 A
      • 单据 1
      • 单据 2
      • 单据3

我不知道如何实现这一点。

I have following models with associations:

class Order < ActiveRecord::Base
  has_many :guests
  has_many :customers, :through => :guests
  accepts_nested_attributes_for :customers
end

class Customer < ActiveRecord::Base
   has_many :guests
   has_many :orders, :through => :guests
   has_many :slips
   accepts_nested_attributes_for :slips
end

class Slip < ActiveRecord::Base
   belongs_to :order
   belongs_to :customer
end

class Guest < ActiveRecord::Base
  belongs_to :order
  belongs_to :customer
end

My nested form looks like this:

<!-- general form -->
<%= form_for(@order) do |f| %>
    <% f.fields_for :customers do |builder| %>
        <%= render "customer_fields", :f => builder %>
    <% end %>
    <%= f.submit %>
<% end %>

<!-- partial customer_fields -->
<p>
    <%= f.label :name%><%= f.text_field :name %>
    <% f.fields_for :slips do |builder| %>
        <%= render "slip_fields", :f => builder %>
    <% end %>
</p>

<!-- partial slip_fields -->
<p><%= f.label :quantity%><%= f.text_field :quantity %></p>

With this setup saving an order works as expected, but I need the order_id to be saved with the slip, so I have a reference between order <-> slip. With this setup I loose the reference. I can get all associated customers, but I'll get all associated slips of the customer related to the order or not.


Here the fields of my models:
Order -> id
Customer -> id
Guest -> id, order_id, customer_id
Slip -> id, order_id, customer_id


The result of an order should look like this

  • Order
    1. Customer A
      • Slip 1
      • Slip 2
    2. Customer B
      • Slip 1
      • Slip 2
    3. Customer A
      • Slip 1
      • Slip 2
      • Slip 3

I've no idea how to accomplish this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

可是我不能没有你 2024-11-07 17:15:01

至于您无法为不存在的订单返回 order_id ,您可以执行此挂钩(我还没有测试它,所以您可能需要修复它)

def create
  customers = params[:order].delete :customers_attributes
  @order = Order.new params[:order]
  if @order.save
    customers.each{|c| c[:slips_attributes].each{|s| s[:order_id] = @order.id} }
    @order.customers_attributes = customers
    @order.save
  end
end

def update
  @order = Order.find params[:id]
  params[:order][:customers_attributes].each{|c| c[:slips_attributes].each{|s| s[:order_id] = @order.id} }
  @order = Order.update_attributes params[:order]
  @order.save
end

另外您也可以最好将所有这些逻辑删除到您的模型中,您可以将其稍微干燥一下。这仅涉及理解一种方法。

针对您的 ID 冲突UPD。这又只是一个草图

def create
  customers = params[:order].delete :customers_attributes
  @order = Order.new params[:order]
  @order.customer_ids = customers.inject([]){|a,h| a << h[:b] if h[:b]; a}
  if @order.save
    customers.each{|c| c[:slips_attributes].each{|s| s[:order_id] = @order.id} }
    @order.customers_attributes = customers
    @order.save
  end
end

def update
  @order = Order.find params[:id]
  @order.customer_ids = params[:order][:customers_attributes].inject([]){|a,h| a << h[:b] if h[:b]; a}
  params[:order][:customers_attributes].each{|c| c[:slips_attributes].each{|s| s[:order_id] = @order.id} }
  @order = Order.update_attributes params[:order]
  @order.save
end

As far as you can't return order_id for order that isn't exist you can do this hook (I haven't test it, so you'll maybe need to fix it)

def create
  customers = params[:order].delete :customers_attributes
  @order = Order.new params[:order]
  if @order.save
    customers.each{|c| c[:slips_attributes].each{|s| s[:order_id] = @order.id} }
    @order.customers_attributes = customers
    @order.save
  end
end

def update
  @order = Order.find params[:id]
  params[:order][:customers_attributes].each{|c| c[:slips_attributes].each{|s| s[:order_id] = @order.id} }
  @order = Order.update_attributes params[:order]
  @order.save
end

Also you'd better to remove all this logic into your model and you can dry it a little. This only about understanding an approach.

UPD for your ID collisions. It is only a scetch again

def create
  customers = params[:order].delete :customers_attributes
  @order = Order.new params[:order]
  @order.customer_ids = customers.inject([]){|a,h| a << h[:b] if h[:b]; a}
  if @order.save
    customers.each{|c| c[:slips_attributes].each{|s| s[:order_id] = @order.id} }
    @order.customers_attributes = customers
    @order.save
  end
end

def update
  @order = Order.find params[:id]
  @order.customer_ids = params[:order][:customers_attributes].inject([]){|a,h| a << h[:b] if h[:b]; a}
  params[:order][:customers_attributes].each{|c| c[:slips_attributes].each{|s| s[:order_id] = @order.id} }
  @order = Order.update_attributes params[:order]
  @order.save
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文