this is my model 'Order' and the 'Order_item' model has association with it
class Order < ApplicationRecord has_many :order_items belongs_to :user
before_save :set_subtotal
def subtotal
order_items.collect { |order_item| order_item.valid? ? order_item.unit_price * order_item.quantity : 0 }.sum
end
private
def set_subtotal
self[:subtotal] = subtotal
end
end
2nd model:
class OrderItem < ApplicationRecord
belongs_to :product
belongs_to :order
before_save :set_unit_price
before_save :set_total
def unit_price
# If there is a record
if persisted?
self[:unit_price]
else
product.price
end
end
def total
return unit_price * quantity
end
private
def set_unit_price
self[:unit_price] = unit_price
end
def set_total
self[:total] = total * quantity
end
end
i am trying to check the test case of RSPEC for the 'SUbtotal' function but i can't seem to find the logic
Rspec model file: Order
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe Order, type: :model do
let(:user) { FactoryBot.create(:user) }
let(:subtotal) { FactoryBot.create(:order, subtotal: 1000) }
let(:items) { FactoryBot.create(:order_item) }
describe 'callbacks' do
it { is_expected.to callback(:set_subtotal).before(:save) }
end
describe 'associations' do
it { is_expected.to belong_to(:user) }
it { is_expected.to have_many(:order_items) }
end
#Gives Error i dont know how to get this
# describe 'subtotal' do
# it 'it should calculate the subtotal' do
# expect(Order.subtotal).to eq(1000)
# end
# end
end
CodePudding user response:
It looks like you're trying to call an instance method on the class. If you change to call subtotal on an instance you'll see a different error.
Order.new.subtotal
should have that defined.
To get your call to work in the spec you would need the method defined on the class with self
.
def self.subtotal
...
end
CodePudding user response:
Like @nikkypx already said you're calling an instance method on the class itself.
In your test setup you created an instance of Order named subtotal
.
So to make it work you'd have to change your test to:
expect(subtotal.subtotal).to eq(1000)
Now since you named your instances funky it sounds confusing. More logical would be to name the Order instance order
.
let(:order) { FactoryBot.create(:order, subtotal: 1000) }