Как сослаться на этот текущий 'votable' элемент в действии в Rails (например, @post и @comment)? - PullRequest
0 голосов
/ 08 февраля 2012

У меня есть две модели: Post и Comment , которые имеют полиморфную ассоциацию с другой моделью под названием Голосовать .

post.rb и comment.rb имеют has_many :votes, :as => :votable, :dependent => :destroy voice.rb имеет belongs_to :votable, :polymorphic => true

Этот контроллер имеет два действия, одно для суммирования голосов за Сообщение и другие для Комментарий :

controllers / избирателей_controller.rb:

class VotesController < ApplicationController
  def vote_up
    @post = Post.find(params[:id])

    if @post.votes.exists?(:user_id => current_user.id)
      @notice = 'You already voted'
    else
      @vote = @post.votes.create(:user_id => current_user.id, :polarity => 1)
    end

    respond_to do |format|
      format.js
    end
  end

  def vote_up2
    @comment = Comment.find(params[:id])

    if @comment.votes.exists?(:user_id => current_user.id)
      @notice2 = 'You already voted'
    else
      @vote2 = @comment.votes.create(:user_id => current_user.id, :polarity => 1)
    end

    respond_to do |format|
      format.js
    end
  end
end

Я думаю, что это излишне.Можно ли использовать одно имя для ссылки на текущий голосовой элемент или @ post и @ comment ?

Редактировать

rout.rb:

 get 'votes/:id/vote_up' => 'votes#vote_up', as: 'vote_up'
 get 'votes/:id/vote_down' => 'votes#vote_down', as: 'vote_down'

1 Ответ

1 голос
/ 09 февраля 2012

Действие vote_up должно быть реализовано в вашем контроллере posts и comments соответственно. Пользователи голосуют за сообщения или комментарии, но не голосуют.

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

в каталоге lib, создайте votable.rb

module Votable
  def up_vote_from(usr)
    place_vote(1, usr.id)
  end

  def down_vote_from(usr)
    place_vote(-1, usr.id)
  end

  private

  def place_vote(direction, usr_id)
    v = self.votes.find_or_create_by_user_id(usr_id)
    v.update_attribute(:polarity, direction)
  end
end

(Этот пересмотренный код изменит исходный голос пользователя, если он проголосует снова. Методы голосования вернутся true, если голос сохранится, false в противном случае.)

В каждой голосовой модели, такой как post.rb и comment.rb, добавьте эту строку, чтобы смешать методы голосования:

include Votable

Теперь это можно сделать в контроллере:

@post.up_vote_from current_user # => true

Что касается реализации, то в результате вы получите некоторое повторение в ваших контроллерах / маршрутах.

В каждом голосовом контроллере установите что-то вроде:

def cast_vote
  @post = Post.find params[:id]
  if @post.call("#{params[:updown]}_vote_from", current_user)
    respond_to do |format|
      format.js
    end
  else
    head :not_found
  end
end

(ожидается .../posts/123/vote/up для повышения, .../posts/123/vote/down для снижения.)

затем добавьте каждый ресурс, чтобы включить ваш метод голосования:

resources :posts do
  member do
    post 'vote/:updown', :to => "posts#cast_vote", :as => :vote_on
  end
end

, который можно вызвать в ваших представлениях с помощью:

<%= button_to "Up", :url => vote_on_post_path(@post, "up"), :remote => true %>
<%= button_to "Down", :url => vote_on_post_path(@post, "down"), :remote => true  %>

Это намного меньше работы, чем кажется. Это будет иметь смысл, как только вы положите его на место. Это будет иметь больше смысла, если вы закодируете его вручную, а не копируете и вставляете. :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...