Reputation: 17631
I'm facing kind of a tricky challenge here, maybe one of you could help me on this. Nothing too hard, I just don't know the good way to go. Here comes:
I have 2 models:
Activity
and Comment
I'm using MongoID here with a famous gem to handle votes (likes). It only take care of embedding a vote model inside an Activity
or a Comment
.
This means that I don't have a Like
model.
How ever I would like to be able to "like" an "activity" and/or a "comment". My guess is to go with a single Controller named LikesController
with 2 methods for both liking or unliking an item.
I would then have this kind of routes:
resources :activities, :only => [] do
resources :comments, :only => [:create, :destroy]
resources :likes, :only => [:create, :destroy]
end
resources :comments, :only => [] do
resources :likes, :only => [:create, :destroy]
end
Here are the given routes from bundle exec rake routes
:
activity_comments POST /activities/:activity_id/comments(.:format) comments#create
activity_comment DELETE /activities/:activity_id/comments/:id(.:format) comments#destroy
activity_likes POST /activities/:activity_id/likes(.:format) likes#create
activity_like DELETE /activities/:activity_id/likes/:id(.:format) likes#destroy
comment_likes POST /comments/:comment_id/likes(.:format) likes#create
comment_like DELETE /comments/:comment_id/likes/:id(.:format) likes#destroy
Now I would like to have a "Like" / "Unlike" link in some view page pointing to the LikesController
on the corresponding actions (create => like ; destroy => unlike).
The only thing is that I don't know how to create the link_to
with the good path.
Here is what I have so far:
link_to 'Like', eval("#{item.class.name.downcase}_likes_path(item)"), :method => 'post'
link_to 'Unlike, eval("#{item.class.name.downcase}_likes_path(item)"), :method => 'destroy'
Can anyone give me a tip on how to do that in a cleaner way ?
Here are my models:
class Activity
include Mongoid::Document
include Mongoid::Timestamps
include Mongo::Voteable
has_many :comments, :as => :item
belongs_to :subject, :polymorphic => true
embeds_one :user
validates :user, :presence => true
voteable self, :up => +1, :down => -1
end
class Comment
include Mongoid::Document
include Mongoid::Timestamps
include Mongo::Voteable
belongs_to :item, :polymorphic => true
embeds_one :user
field :text, :type => String, :default => nil
validates :text, :presence => true
validates :user, :presence => true
attr_accessible :text, :user
voteable self, :up => +1, :down => -1
end
You have to keep in mind that a lot of futur objects could be "likeable" also, that's why I choose to go with a LikesController
beside having duplicate method inside each item's controller to handle "likes" and "unlikes". Maybe I'm wrong ?
Thank you.
Upvotes: 0
Views: 496
Reputation: 12235
I would go with a view helper here.
def likehelper(likable)
if likable.is_a? Activity
# return activitycommentpath..
...
end
and then in your view link_to 'Like', likehelper(item)
, and the same for Unlike
. If other objects become "likable", all you would have to do is add a new "rule" to your helper.
Upvotes: 2