I can’t get my subscription to update with my product and also duplicate the attributes of the product to the same fields as my subscription table.
My associations are, subscriptions and products belong to a User but a Product has many subscriptions.
Subscription.rb
class Subscription
belongs_to :subscriber, :class_name => "User"
belongs_to :subscribable, :polymorphic => true
end
Product.rb
class Product
belongs_to :user
has_many :subscriptions, :as => :subscribable, :dependent => :destroy
end
User.rb
class User
has_many :products, :dependent => :destroy
has_many :subscriptions, :foreign_key => :subscriber_id, :dependent => :destroy
end
Then the Product and Subscription table with the same columns that I’m trying to duplicate:
create_table :products do |t|
t.string :name
t.decimal :price
t.integer :user_id
end
create_table :subscriptions do |t|
t.string :name
t.decimal :price
t.integer :subscriber_id # same as user_id
t.integer :subscribable_id
t.string :subscribable_type
end
ProductsController
def edit
@product = Product.find(params[:id])
end
def update
@product = Product.find(params[:id])
if @product.update_attributes(params[:product])
redirect_to(@product, :notice => 'Successfully Updated.')
else
render :back
end
end
ProductObserver
class ProductObserver < ActiveRecord::Observer
def after_update(product)
if self.subscriptions.find_by_subscribable_id_and_subscribable_type(subscribable_id, subscribable_type)
subscription = Subscription.find_by_subscribable_id_and_subscribable_type(subscribable_id, subscribable_type)
self.subscription.update_attributes(params[:subscription]).select{ |key, _| Subscription.attribute_names.include? key })
end
end
end
What the after_update is suppose to do is:
- Check if a subscription for the particular product exist and if it does….
- Update the current users subscription with the products new edited attributes.
Right now, the Subscription doesn’t update when the Product does. What do I need to fix about this code to get it to do this? What about when duplicating the product fields to its subscription?
Not sure if that was just a typo, but your observer is wrong.
selfis not your product in an observer. Instead you should useproduct(the given parameter) instead.Secondly your lookup of the subscriptions seems wrong too. You are using
subscribable_idandsubscribable_typewhich are not defined and thus justnil. I think you want to useproduct.idand'Product', but then you could just iterate over all subscriptions of the product.product.subscriptionsreturns allsubscriptionslinked to that product.Lastly, if you are going to keep
priceandnameof a subscription always in sync with the linked product, why do not something like this instead:and inside your subscription model do
Hope this helps.