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) }

