ruby on rails - Voting for nested objects using the Acts As Votable gem -
i have restaurant model has_many :dishes, through: dish_categories. found post shows how write view code necessary things going acts votable gem. situation differs being dish model nested resource that's being voted upon.
i tried translating provided code no avail. @ point should create new controller dishes , place votable actions there? if how setup route can accomplish on restaurant's show page?
models
class restaurant < activerecord::base has_many :dish_categories, dependent: :destroy has_many :dishes, through: :dish_categories end class dishcategory < activerecord::base belongs_to :restaurant has_many :dishes, dependent: :destroy delegate :name, to: :dish_category, prefix: "category" delegate :restaurant, to: :dish_category end class dish < activerecord::base belongs_to :dish_category end restaurants controller
... def upvote @restaurant = restaurant.find(params[:id]) @dish = dish.find(params[:id]) @dish.liked_by current_user redirect_to @restaurant end def downvote @restaurant = restaurant.find(params[:id]) @dish = dish.find(params[:id]) @dish.disliked_by current_user redirect_to @restaurant end ... routes
resources :restaurants member put "upvote", to: "restaurants#upvote" put "downvote", to: "restaurants#downvote" end end restaurants - show view
... <% @restaurant.dishes.each |dish| %> <div> <h2><%= dish.category_name %></h2> <b><%= dish.name %></b> <%= link_to "upvote", like_restaurant_path(dish), method: :put %> <%= link_to "downvote", dislike_restaurant_path(dish), method: :put %> </div> <% end %>
a number of things needed done work. first order of business moving controller action dishes controller. added 2 more actions: unlike , undislike toggle functionailty.
note: logic authenticating non-registered users liking/disliking dishes still need written should started.
dishes controller
class dishescontroller < applicationcontroller before_action :load_restaurant_and_dish, only: [:like, :unlike, :dislike, :undislike] def @dish.liked_by current_user redirect_to @restaurant end def unlike @dish.unliked_by current_user redirect_to @restaurant end def dislike @dish.disliked_by current_user redirect_to @restaurant end def undislike @dish.undisliked_by current_user redirect_to @restaurant end private def load_restaurant_and_dish @dish = dish.find(params[:id]) @restaurant = @dish.restaurant end end next configuring routes correspond restaurant , dish models:
routes
resources :restaurants resources :dishes, only: [:like, :unlike, :dislike, :undislike] member put "like", to: "dishes#like" put "unlike", to: "dishes#unlike" put "dislike", to: "dishes#dislike" put "undislike", to: "dishes#undislike" end end end i ended refactoring show view , created few partials reduce clutter there's little bit of logic involved:
restaurants - show view
... <%= render "restaurants/dish_partials/dishes" %> ... dishes partial
<% @dishes.each |dish| %> <div> <h2><%= dish.category_name %></h2> <span><b><%= dish.name %></b></span> <%= render "restaurants/dish_partials/like_toggle", dish: dish %> </div> <% end %> like toggle partial
<% if current_user.liked? dish %> <%= link_to "unlike", unlike_restaurant_dish_path(@restaurant, dish), method: :put %> <% else %> <%= link_to "like", like_restaurant_dish_path(@restaurant, dish), method: :put %> <% end %> <% if current_user.disliked? dish %> <%= link_to "undislike", undislike_restaurant_dish_path(@restaurant, dish), method: :put %> <% else %> <%= link_to "dislike", dislike_restaurant_dish_path(@restaurant, dish), method: :put %> <% end %>
Comments
Post a Comment