I am starting to put together an application that includes, products, a shopping cart and payments. You start by adding the product to your cart by going to /products. Then if you navigate to /cart the system will populate your list of products ready to checkout. The plan is to link the "total price" attribute within the carts table into the payments table.
How do I go about linking two attributes from separate tables to make them the same? I have marked the two attributes that need to be the same, "total price" and "amount."
create_payments.rb
class CreatePayments < ActiveRecord::Migration
def change
create_table :payments do |t|
t.string :first_name
t.string :last_name
t.string :last4
***t.decimal :amount, precision: 12, scale: 3***
t.boolean :success
t.string :authorization_code
t.timestamps null: false
end
end
end
create_order_items.rb
class CreateOrderItems < ActiveRecord::Migration
def change
create_table :order_items do |t|
t.references :product, index: true, foreign_key: true
t.references :order, index: true, foreign_key: true
t.decimal :unit_price, precision: 12, scale: 3
t.integer :quantity
***t.decimal :total_price, precision: 12, scale: 3***
t.timestamps null: false
end
end
end
Please let me know if any further files will be needed to help troubleshoot the problem. Thank you in advance for any type of assistance!
I think what you're looking for here is to write a custom "getter" method, ie a virtual attribute. You could also overwrite save
or use an (activerecord callback)[ http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html]
For example:
class Payment < ActiveRecord::Base
has_many :order_items
# --------
# option 1
# --------
def amount
# sums up the total price of the associated order items
self.order_items.pluck(:price).sum
end
# --------
# option 2
# --------
def save(*args)
self.amount = self.order_items.pluck(:price).sum
super(*args)
end
# ----------
# option 3
# ----------
before_save :set_amount
def set_amount
self.amount = self.order_items.pluck(:price).sum
end
end
with the first option ("custom getter"), the aggregate column is not stored in the database and is dynamically recalculated each time it's value is accessed.
With the second option ("overriding save"), the amount
column will be automatically set whenever save
is called on a record.
The third option is probably the best in my opinion. It basically does the same thing as option 2, but looks a little cleaner.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.