ruby - Rails 3: Polymorphic liking of Entities by User, how? -


background:

i followed tutorial here setup polymorphic user favorites data model in application. allows me let user make pretty entity in system add 'has_many :favorites, :as => :favorable' line model favorite. plan on using implement facebook style 'like' system several other similar systems.

to start off added favoritability post model (each user can create status updates on facebook). have done , unit tested know data model sound , functioning either side of relationship (user , post).

details:

  • i have home controller single index method , view.

  • on index view render out posts user , user's friends

  • i want user able posts friends

  • the posts controller has create , destroy method associated routes (not full fledged resource) , through post method via ajax posts created , deleted without issue

where stuck

  • how add link or button add post user's favorites?

  • according tutorial way create new favorite through polymorphic association post.favorites.build(:user_id => current_user.id). direction build handles pulling out post's id , type , have pass in user's id

  • do use ajax form post favorites controller create , destroy method similar post controller?

  • i still struggling uncross wires in brain asp.net n-tier web application development on rails mvc. hasn't been bad until ;)

  • i bet there gems out there might need learn , best way suffer through it. maybe tutorial or sample code has implemented liking functionality within application helpful.

thanks in advance assistance!

jaap, appreciate comment on question. after writing question pretty didn't want wait because real learning takes place through trial , error, errored ;)

it turns out suggested pretty in line ended doing myself (it's nice find out decide others well, love sanity check value of all).

so here did , working through post-backs. need implement ajax , style it:

my favorite model because polymorphic favorites model requires entity can favorited once user added validations 'scopes' indicate each attribute has unique in scope of other 2 required attributes. solves issue of multiple favorites same user.

class favorite < activerecord::base   before_save :associate_user    belongs_to :favorable   belongs_to :user    # validations   validates :user_id, :presence => true,             :uniqueness => {:scope => [:favorable_id, :favorable_type], :message => "item in favorites list."}   validates :favorable_id, :presence => true,             :uniqueness => {:scope => [:user_id, :favorable_type], :message => "item in favorites list."}   validates :favorable_type, :presence => true,             :uniqueness => {:scope => [:favorable_id, :user_id], :message => "item in favorites list."}    # callbacks   protected    def associate_user     unless self.user_id       return self.user_id = session[:user_id] if session[:user_id]       return false     end   end  end 

my user model (that relevant): added 2 methods, get_favorites same favorable 1 tutorial , favorite? method checks see if entity in question has been added user's favorites.

class user < activerecord::base     # relationships   has_many  :microposts, :dependent => :destroy   has_many  :favorites    # methods   def favorite?(id, type)     if get_favorites({:id => id, :type => type}).length > 0       return true     end     return false   end    def get_favorites(opts={})     # polymorphic favoritability: allows model in     # application favorited user.     # favorable_type     type = opts[:type] ? opts[:type] : :topic     type = type.to_s.capitalize      # add favorable_id condition if id provided     con = ["user_id = ? , favorable_type = ?", self.id, type]      # append favorable id query if :id passed option     # function, , append id string "con" array     if opts[:id]       con[0] += " , favorable_id = ?"       con << opts[:id].to_s     end      # return favorite objects matching above conditions     favs = favorite.all(:conditions => con)      case opts[:delve]     when nil, false, :false       return favs     when true, :true       # list of favorited object ids       fav_ids = favs.collect{|f| f.favorable_id.to_s}        if fav_ids.size > 0         # turn capitalized favorable_type actual class constant         type_class = type.constantize          # build query selects         query = []         fav_ids.size.times           query << "id = ?"         end         type_conditions = [query.join(" , ")] + fav_ids          return type_class.all(:conditions => type_conditions)       else         return []       end     end   end  end 

my micropost model (that relevant): note polymorphic association in has_many relationship titled :favorites.

class micropost < activerecord::base   attr_accessible :content    # scopes   default_scope :order => 'microposts.created_at desc'    # relationships   belongs_to  :user   has_many  :favorites, :as => :favorable # polymorphic association    # validations   validates :content, :presence => true, :length => { :minimum => 1, :maximum => 140 }   validates :user_id, :presence => true  end 

my micropost form: can see passing in entity mapped favorite model local variable 2 favorite forms 'local_entity'. way can pull out id , type of entity polymorphic association.

<div class="post">     <span class="value">       <%= micropost.content %>     </span>     <span>         <% if current_user.favorite?(micropost.id, micropost.class.to_s) %>             <%= render :partial => 'favorites/remove_favorite', :locals => {:local_entity => micropost} %>         <% else %>             <%= render :partial => 'favorites/make_favorite', :locals => {:local_entity => micropost} %>         <% end %>     </span>     <span class="timestamp">         posted <%= time_ago_in_words(micropost.created_at) %> ago.     </span>     <div class="clear"></div> </div> 

my make favorite form:

<%= form_for current_user.favorites.build |f| %>     <div><%= f.hidden_field :favorable_id, :value => local_entity.id %></div>     <div><%= f.hidden_field :favorable_type, :value => local_entity.class.to_s %></div>     <div class="actions"><%= f.submit "make favorite" %></div> <% end %> 

my remove favorite form:

<%= form_for current_user.get_favorites(                      {:id => local_entity.id,                       :type => local_entity.class.to_s}),                       :html => { :method => :delete } |f| %>     <div class="actions"><%= f.submit "remove favorite" %></div> <% end %> 

Comments

Popular posts from this blog

linux - Using a Cron Job to check if my mod_wsgi / apache server is running and restart -

actionscript 3 - TweenLite does not work with object -

jQuery Ajax Render Fragments OR Whole Page -