Комментарий к голосованию с актами голосования

Я пытаюсь внедрить систему голосования в комментарии к сообщениям, используя Acts как драгоценный камень для голосования. На этом этапе я получаю эту ошибку

ActionController::UrlGenerationError in Posts#show 

с последующим -

No route matches {:action=>"upvote", :controller=>"comments", :id=>nil, :post_id=>#<Comment id: 5, post_id: 3, body: "abc", created_at: "2014-01-12 20:18:00", updated_at: "2014-01-12 20:18:00", user_id: 1>, :format=>nil} missing required keys: [:id]. 

Я довольно слаб с маршрутами.

мои маршруты.rb

resources :posts do
  resources :comments do
    member do
      put "like", to: "comments#upvote"
      put "dislike", to: "comments#downvote"
    end
  end
end

контроллер комментариев

def upvote
  @post = Post.find(params[:post_id])
  @comment = @post.comments.find(params[:id])
  @comment.liked_by current_user
  redirect_to @post
end

def downvote
  @post = Post.find(params[:post_id])
  @comment = @post.comments.find(params[:id])
  @comment.downvote_from current_user
  redirect_to @post
end

_comment.html.erb

<%= link_to "Upvote", like_post_comment_path(comment), method: :put %>
<%= link_to "Downvote", dislike_post_comment_path(comment), method: :put %>

person Shuvro    schedule 19.01.2014    source источник


Ответы (2)


Вы также должны передать id поста в like_post_comment_path как like_post_comment_path(post, comment)

person Igor Drozdov    schedule 19.01.2014
comment
Спасибо. Но я предполагаю, что это должно быть как_post_comment_path(@post, comment). принимая его как правильный, поскольку он ведет к решению. - person Shuvro; 19.01.2014

Прелесть этого драгоценного камня в том, что вы можете легко прикрепить голоса к любому объекту. Так почему бы не создать контроллер голосов, который может обрабатывать голоса для любого объекта из любого места вашего приложения? Вот мое решение:

routes.rb

  resources :votes, only: [] do
    get 'up', on: :collection
    get 'down', on: :collection
  end

votes_controller.rb

class VotesController < ApplicationController
  before_action :authenticate_user!
  before_action :identify_object

  def up
    @object.liked_by current_user
    redirect_to :back # redirect to @object if you want
  end

  def down
    @object.downvote_from current_user
    redirect_to :back # redirect to @object if you want
  end

  private

  def identify_object
    type = params[:object]
    @object = type.constantize.find(params[:id])
  end
end

Затем ссылки для голосования в вашем представлении

up_votes_path(object:'Post', id:post.id)
down_votes_path(object:'Post', id:post.id)
person Abram    schedule 27.03.2016