Rails 未定义的局部变量或方法 `line_item'
Rails undefined local variable or method `line_item'
你好,我 运行 在为我在我的网站上构建的购物车创建此条件时遇到了一些麻烦,以便在零件销售时显示总计。在我的架构中,我有零件 line_items,它有零件和手推车的 ID,以及手推车。零件具有折扣属性。如果某个零件有折扣,它将显示该零件的折扣和新价格。我的 line_items 有一个名为 line_item_discount 的方法,如果一个部分包含折扣,它将创建一个新的部分总和。虽然它显示零件、折扣和新价格,但购物车总计没有更新它。
我在这里创建了一个名为 total_price_with_discount 的方法
class Cart < ActiveRecord::Base
has_many :order_items
belongs_to :user
has_many :line_items, dependent: :destroy
def add_part(part_id)
current_part = line_items.find_by(part_id: part_id)
if current_part
current_part.quantity += 1
else
current_part = line_items.build(part_id: part_id)
end
current_part
end
def total_price
line_items.to_a.sum { |item| item.total_price}
end
def total_price_with_discount
line_items.to_a.sum { |item| item.total_price.line_item_discount}
end
现在我卡住的地方是 _cart partial 我试图创建一个条件,如果一个零件有折扣,它将使用 total_price_with_discount 方法,但如果一个零件没有折扣,它将使用 total_price。我已经尝试了很多方法来创建条件,但我不断收到这样的消息
出于某种原因,购物车没有 line_items 实例或它出现的部分。
这是我的推车、零件和 line_items
表格
create_table "carts", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id"
t.integer "quantity"
t.decimal "subtotal"
end
create_table "parts", force: :cascade do |t|
t.string "name"
t.text "description"
t.integer "category_id"
t.integer "price"
t.boolean "active"
t.integer "discount"
t.string "image"
t.integer "quantity"
end
create_table "line_items", force: :cascade do |t|
t.integer "part_id"
t.integer "cart_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "quantity", default: 1
end
我的零件模型
class Part < ActiveRecord::Base
has_many :order_items
has_many :line_items
before_destroy :ensure_not_referenced_by_any_line_item
def ensure_not_referenced_by_any_line_item
if line_items.empty?
return true
else
errors.add(:base, 'Line Items present')
return false
end
end
def subtotal
parts.collect { |part| part.valid? ? (part.quantity * part.unit_price) : 0}.sum
end
def apply_discount
price - (discount.to_f/100 * price)
end
end
我的line_items模特
class LineItem < ActiveRecord::Base
belongs_to :part
belongs_to :cart
def total_price
part.price * quantity
end
def line_item_discount
part.price - (part.discount.to_f/100 * part.price) * quantity
end
end
这是抛出错误的局部视图
<h2>Your Cart</h2> <table>
<%= render(cart.line_items) %>
<tr class="total_line">
<td colspan="2">Total</td>
<%unless cart.line_items.part.discount?%>
<td class="total_cell"><%= number_to_currency(cart.total_price) %></td>
<%end%>
<%if cart.line_items.part.discount?%>
<td class="total_cell"><%= number_to_currency(cart.total_price_with_discount) %></td>
<%end%>
</tr>
</table>
<%= button_to 'Empty cart', cart, method: :delete, data: { confirm: 'Are you sure?' } %>
感谢您对此的任何帮助和建议
在您看来,您正在调用 cart.line_items.part
,但 line_items
是多个 LineItem
对象的集合,.part
不是该集合对象的有效方法。
如您在错误中所见,ActiveRecord::Associations::CollectionProxy
缺少 part
方法。
您应该在 LineItem
上创建一个范围,例如:
scope :with_discounted_part, { joins(:part).where.not(part: { discount: nil }) }
然后在你看来你可以这样做:
<% if cart.line_items.with_discounted_part %>
我要在 Cart
模型中添加:
has_many :parts, through: :line_items
向 Part
模型添加作用域:
scope :with_discounts, -> { where.not(discount: nil) }
然后将视图更改为:
<td class="total_cell">
<%if cart.parts.with_discount.any?%>
<%= number_to_currency(cart.total_price_with_discount) %>
<%else%>
<%= number_to_currency(cart.total_price) %>
<%end%>
</td>
更新:我相信下面的代码比上面的代码更有效,但我会提供两个选项供您选择。
下面我们将始终在 LineItem
模型中的 total_price
方法中使用 line_item_discount
:
def total_price
(part.price * quantity) - line_item_discount
end
def line_item_discount
return 0 if part.discount.blank?
(part.discount.to_f/100 * part.price) * quantity
end
那么您甚至不需要视图中的 if 语句,total_price
两种方式都可以:
<td class="total_cell"><%= number_to_currency(cart.total_price) %></td>
然后您可以从 Cart
模型中删除 total_price_with_discount
方法。
我们还可以在 Cart
模型中调整 total_price
方法:
(适用于任一代码选择)
def total_price
line_items.sum(:total_price)
end
你好,我 运行 在为我在我的网站上构建的购物车创建此条件时遇到了一些麻烦,以便在零件销售时显示总计。在我的架构中,我有零件 line_items,它有零件和手推车的 ID,以及手推车。零件具有折扣属性。如果某个零件有折扣,它将显示该零件的折扣和新价格。我的 line_items 有一个名为 line_item_discount 的方法,如果一个部分包含折扣,它将创建一个新的部分总和。虽然它显示零件、折扣和新价格,但购物车总计没有更新它。
我在这里创建了一个名为 total_price_with_discount 的方法
class Cart < ActiveRecord::Base
has_many :order_items
belongs_to :user
has_many :line_items, dependent: :destroy
def add_part(part_id)
current_part = line_items.find_by(part_id: part_id)
if current_part
current_part.quantity += 1
else
current_part = line_items.build(part_id: part_id)
end
current_part
end
def total_price
line_items.to_a.sum { |item| item.total_price}
end
def total_price_with_discount
line_items.to_a.sum { |item| item.total_price.line_item_discount}
end
现在我卡住的地方是 _cart partial 我试图创建一个条件,如果一个零件有折扣,它将使用 total_price_with_discount 方法,但如果一个零件没有折扣,它将使用 total_price。我已经尝试了很多方法来创建条件,但我不断收到这样的消息
出于某种原因,购物车没有 line_items 实例或它出现的部分。
这是我的推车、零件和 line_items
表格create_table "carts", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id"
t.integer "quantity"
t.decimal "subtotal"
end
create_table "parts", force: :cascade do |t|
t.string "name"
t.text "description"
t.integer "category_id"
t.integer "price"
t.boolean "active"
t.integer "discount"
t.string "image"
t.integer "quantity"
end
create_table "line_items", force: :cascade do |t|
t.integer "part_id"
t.integer "cart_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "quantity", default: 1
end
我的零件模型
class Part < ActiveRecord::Base
has_many :order_items
has_many :line_items
before_destroy :ensure_not_referenced_by_any_line_item
def ensure_not_referenced_by_any_line_item
if line_items.empty?
return true
else
errors.add(:base, 'Line Items present')
return false
end
end
def subtotal
parts.collect { |part| part.valid? ? (part.quantity * part.unit_price) : 0}.sum
end
def apply_discount
price - (discount.to_f/100 * price)
end
end
我的line_items模特
class LineItem < ActiveRecord::Base
belongs_to :part
belongs_to :cart
def total_price
part.price * quantity
end
def line_item_discount
part.price - (part.discount.to_f/100 * part.price) * quantity
end
end
这是抛出错误的局部视图
<h2>Your Cart</h2> <table>
<%= render(cart.line_items) %>
<tr class="total_line">
<td colspan="2">Total</td>
<%unless cart.line_items.part.discount?%>
<td class="total_cell"><%= number_to_currency(cart.total_price) %></td>
<%end%>
<%if cart.line_items.part.discount?%>
<td class="total_cell"><%= number_to_currency(cart.total_price_with_discount) %></td>
<%end%>
</tr>
</table>
<%= button_to 'Empty cart', cart, method: :delete, data: { confirm: 'Are you sure?' } %>
感谢您对此的任何帮助和建议
在您看来,您正在调用 cart.line_items.part
,但 line_items
是多个 LineItem
对象的集合,.part
不是该集合对象的有效方法。
如您在错误中所见,ActiveRecord::Associations::CollectionProxy
缺少 part
方法。
您应该在 LineItem
上创建一个范围,例如:
scope :with_discounted_part, { joins(:part).where.not(part: { discount: nil }) }
然后在你看来你可以这样做:
<% if cart.line_items.with_discounted_part %>
我要在 Cart
模型中添加:
has_many :parts, through: :line_items
向 Part
模型添加作用域:
scope :with_discounts, -> { where.not(discount: nil) }
然后将视图更改为:
<td class="total_cell">
<%if cart.parts.with_discount.any?%>
<%= number_to_currency(cart.total_price_with_discount) %>
<%else%>
<%= number_to_currency(cart.total_price) %>
<%end%>
</td>
更新:我相信下面的代码比上面的代码更有效,但我会提供两个选项供您选择。
下面我们将始终在 LineItem
模型中的 total_price
方法中使用 line_item_discount
:
def total_price
(part.price * quantity) - line_item_discount
end
def line_item_discount
return 0 if part.discount.blank?
(part.discount.to_f/100 * part.price) * quantity
end
那么您甚至不需要视图中的 if 语句,total_price
两种方式都可以:
<td class="total_cell"><%= number_to_currency(cart.total_price) %></td>
然后您可以从 Cart
模型中删除 total_price_with_discount
方法。
我们还可以在 Cart
模型中调整 total_price
方法:
(适用于任一代码选择)
def total_price
line_items.sum(:total_price)
end