迭代多个连接表以显示视图中的项

时间:2017-10-12 19:07:50

标签: ruby-on-rails ruby

我有一个Order模型,一个LineItem模型和一个Product模型。以下是协会。我正在试图弄清楚如何访问Product模型中的name属性。我的第一个想法是迭代LineItem表以收集line_items,其中order_id ==在show视图中使用的顺序。然后,迭代新的line_items并从line_item的product_id属性中获取每个产品名称。这必须在一个方法中完成,可能在Order模型中完成。有没有更好的方法可以使用Rails关联完成?我当前的实现导致#Order的未定义方法产品:0x007f5d007305f0

order.rb

class Order < ApplicationRecord
  has_many :line_items
  belongs_to :user

  accepts_nested_attributes_for :line_items

  after_validation :set_amount

  private
  def set_amount
    self.amount = line_items.map(&:product).map(&:cost).inject(:+)
  end
end

product.rb

class Product < ApplicationRecord
    has_many :line_items
end

line_item.rb

class LineItem < ApplicationRecord
  belongs_to :order
  belongs_to :product
end

为了/ show.html.erb

<h3>Customer - <%= @order.user.first_name %> <%= @order.user.last_name %></h3>
<h4>Order Date - <%= @order.created_at.to_s(:date_us) %></h4>

<%= @line_items.each do |item| %>
    <table class="table">
        <thead>
            <tr>
                <th>Product Quantity</th>
                <th>Product Name</th>
                <th class="text-right">Subtotal</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <th scope="row"></th>
                <td><%= item.order.product.name %></td>
                <td class="text-right"></td>
            </tr>
        </tbody>
    </table>
<% end %>
<div class="text-right">
  <h3><%= @order.amount %></h3>
</div>

orders_controller.rb

class OrdersController < ApplicationController
  before_action :authenticate_user!

  def index
    @orders = Order.all

  end

  def show
    @order = Order.find(params[:id])
    @line_items = LineItem.all
  end

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

  def create
    @order = current_user.orders.build(order_params)
    if @order.valid?
      @order.save
      redirect_to order_receipt_path(@order)
    else
      render :new
    end
  end

  private
  def order_params
    params.require(:order).permit(line_items_attributes: [:id, :name, :product_id])
  end

  def products
    @products ||= Product.all
  end
  helper_method :products
end

3 个答案:

答案 0 :(得分:0)

您收到以下错误,因为Order模型没有project关联,但LineItem有。{/ p>

您可能希望按控制器show方法按顺序过滤订单项:

def show
  @order = Order.find(params[:id])
  @line_items = @order.line_items
end

然后迭代它们并显示它们的项目名称:

<h3>Customer - <%= @order.user.first_name %> <%= @order.user.last_name %></h3>
<h4>Order Date - <%= @order.created_at.to_s(:date_us) %></h4>

<%= @line_items.each do |item| %>
    <table class="table">
        <thead>
            <tr>
                <th>Product Quantity</th>
                <th>Product Name</th>
                <th class="text-right">Subtotal</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <th scope="row"></th>
                <td><%= item.product.name %></td>
                <td class="text-right"></td>
            </tr>
        </tbody>
    </table>
<% end %>
<div class="text-right">
  <h3><%= @order.amount %></h3>
</div>

答案 1 :(得分:0)

订单不了解产品。您应该致电item.product.name而不是item.order.product.name

答案 2 :(得分:0)

还要考虑急切加载产品以避免N + 1查询问题。您可以在OrdersController#show action中执行此操作:@order.line_items.includes(:product)