I am basically looking for a way to implement a polymorphic model Subscription in my app right now
There are entries, users and subscriptions in my app right now. A user can subscribe to an entry. Later on, a user can subscribe to something else. Hence polymorphic.
I have been following the rails cast on polymorphic model. However, I have made some modifications:
# Param: {"subscribable_type": "entry|something", "subscribable_id": int}
def create
@subscribable = find_subscribable(params[:subscription])
@subscription = @subscribable.subscriptions.build(params[:subscription])
@subscription.user_id = current_user.id
if @subscription.save
redirect_to :back, :notice => "Successfully created subscription."
else
redirect_to :back, :notice => "Failed creating subscription."
end
end
def find_subscribable(instance_params)
class_name = instance_params["subscribable_type"].classify.constantize
class_name.find(instance_params["subscribable_id"])
end
and in my models:
class Subscription < ActiveRecord::Base
attr_accessible :user_id, :subscribable_id, :subscribable_type
belongs_to :user
belongs_to :subscribable, :polymorphic => true
end
class Entry < ActiveRecord::Base
attr_accessible :title, :body, :img, :author_id
belongs_to :author, :class_name => "User", :foreign_key => "author_id"
has_many :tidbits
has_and_belongs_to_many :tags
has_many :subscriptions, :as => :subscribable
end
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
from the console:
1.9.2p290 :037 > Subscription.last
Subscription Load (0.1ms) SELECT "subscriptions".* FROM "subscriptions" ORDER BY "subscriptions"."id" DESC LIMIT 1
=> #<Subscription id: 3, user_id: 1, subscribable_id: 3, subscribable_type: "entry", created_at: "2011-12-15 07:17:53", updated_at: "2011-12-15 07:17:53">
Somehow, the entry above has no subscriptions:
1.9.2p290 :040 > Entry.find(3).subscriptions
Entry Load (0.2ms) SELECT "entries".* FROM "entries" WHERE "entries"."id" = ? LIMIT 1 [["id", 3]]
Subscription Load (0.2ms) SELECT "subscriptions".* FROM "subscriptions" WHERE "subscriptions"."subscribable_id" = 3 AND "subscriptions"."subscribable_type" = 'Entry'
=> []
What am I doing wrong?
And how should I set up User so that I can access all the user’s entries subscriptions and other forms of subscriptions?
iThe second query is looking for
subscribable_type = 'Entry'(upper case), but the output from the first query shows that the persisted data hassubscribable_type = 'entry'(lower case).You need to change whatever us calling the
createmethod such that it passes uppercaseEntry.