如何在Rails中实现投票?

时间:2013-06-25 10:15:44

标签: ruby-on-rails voting

我在RailsTutorial Michael Hartl chapter 10Micropost并且做了一些额外的事情来为每个微博添加回形针图像。当我向Microphoto添加照片时,我将其称为class CreateMicrophotos < ActiveRecord::Migration def change create_table :microphotos do |t| t.string :content t.integer :user_id t.integer :votes_up t.integer :votes_down t.timestamps end add_index :microphotos, [:user_id, :created_at] end end 现在我做了以下事情:

  1. 正确迁移数据库

    class User < ActiveRecord::Base
      require "paperclip" 
      attr_accessible :name, :email, :password, :password_confirmation, :avatar,
    :avatar_file_name, :avatar_content_type, :avatar_file_size, :avatar_updated_at
      has_secure_password
      has_many :microphotos, dependent: :destroy
      has_attached_file :avatar, :styles => { :large => "120x120>", :medium => "48x48>", :thumb => "26x26>" }
      .
      .
      .
      def feed
        Microphoto
      end
    end
    
  2. 更改微照片模型和控制器

  3. 写一些观点
  4. 这是我的档案:

    用户模型

    class Microphoto < ActiveRecord::Base
      attr_accessible :content, :votes_down, :votes_up, :photoclip,
      :photoclip_file_name, :photoclip_content_type, :photoclip_file_size, :photoclip_updated_at
      belongs_to :user
      has_attached_file :photoclip, :styles => { :large => "500x400>", :medium => "100x80>" }
      validates :content, presence: true, length: { maximum: 140 }  
      validates :user_id, presence: true
      default_scope order: 'microphotos.created_at DESC'
    end
    

    Microphoto模型

    class MicrophotosController < ApplicationController
      before_filter :signed_in_user, only: [:create, :destroy]
      def index
      end
      def create
        @microphoto = current_user.microphotos.build(params[:microphoto])
        if @microphoto.save
          flash[:success] = "Your photo has been uploaded successfully!"
          redirect_to root_url
        else
          render 'static_pages/home'
        end
      end
      def destroy
      end
    end
    

    Microphotos Controller

    anonymousxxx

    我想要发生一件事:

    • 登录用户可以投票给其他用户的Microphotos,但不能投票给他们自己的

      我该怎么办?

    我试图更改微照片控制器更改操作。我知道这可能不是一个真正的问题,但由于我是Rails的新手,我不能那样做。

    [更新1]

    我使用了rake routes建议的方法,但最终出现了此路由错误消息:

      

    没有路线匹配{:controller =&gt;“microphotos”,:action =&gt;“vote_up”,:id =&gt;#}

    使用命令 users GET /users(.:format) users#index POST /users(.:format) users#create new_user GET /users/new(.:format) users#new edit_user GET /users/:id/edit(.:format) users#edit user GET /users/:id(.:format) users#show PUT /users/:id(.:format) users#update DELETE /users/:id(.:format) users#destroy sessions POST /sessions(.:format) sessions#create new_session GET /sessions/new(.:format) sessions#new session DELETE /sessions/:id(.:format) sessions#destroy microphotos POST /microphotos(.:format) microphotos#create microphoto DELETE /microphotos/:id(.:format) microphotos#destroy root / static_pages#home signup /signup(.:format) users#new signin /signin(.:format) sessions#new signout DELETE /signout(.:format) sessions#destroy help /help(.:format) static_pages#help about /about(.:format) static_pages#about terms /terms(.:format) static_pages#terms vote_up PUT /vote_up/:id(.:format) microphotos#vote_up vote_down PUT /vote_down/:id(.:format) microphotos#vote_down 我有:

    ArgumentError

    [更新2]

    在完成他的指示后,我得到了 can't use collection outside resource(s) scope
    config/routes.rb:18:in `block (3 levels) in <top (required)>' config/routes.rb:17:in `block (2 levels) in <top (required)>' config/routes.rb:16:in `block in <top (required)>' config/routes.rb:1:in `<top (required)>'

    routes.rb

    这是16 resources :microphotos do 17 collection do 18 put '/vote_up/:id' => "microphotos#vote_up", :on => collection, :as => :vote_up 19 put '/vote_down/:id' => "microphotos#vote_down", :on => collection, :as => :vote_down 20 end 21 end

    {{1}}

3 个答案:

答案 0 :(得分:3)

您可以使用acts_as_votable gem。

安装gem:

gem 'acts_as_votable', '~> 0.5.0'
bundle

安装并运行迁移:

rails generate acts_as_votable:migration
bundle exec rake db:migrate

Microphoto模型中,您应该:

acts_as_votable

完成此操作后,您可以投票/取消投票microphotos,例如:

@microphoto.liked_by @user1
@microphoto.downvote_from @user2
@microphoto.vote :voter => @user3
@microphoto.vote :voter => @user4, :vote => 'bad'
@microphoto.vote :voter => @user5, :vote => 'like'

答案 1 :(得分:1)

考虑act_as_rateable gem,它可能比Marek Lipka为您解释的特定用例更好地适合您。

答案 2 :(得分:1)

解决方案1(用户可多次投票)

您可以在视图上使用if.. else..语句。

Listing 10.46。添加删除链接到微博部分。

Micropost只能由所有者用户删除。

<% if current_user?(micropost.user) %>
    <%= link_to "delete", micropost, method: :delete,
                                     data: { confirm: "You sure?" },
                                     title: micropost.content %>
  <% end %>

示例(未经测试但希望此帮助):

  # on view (e.g show.html.erb)

  <% if signed_in? && current_user.id != feed_item.user_id %>
    <%= link_to "vote up", vote_up_microphotos_url(feed_item.id), :method => :put %> 
    <%= link_to "vote down", vote_down_microphotos_url(feed_item.id), :method => :put %>
  <% end %>


  # controller
  before_filter :signed_in_user, only: [:create, :destroy, :vote_up, :vote_down]


  def vote_up
    @microphoto = Microphoto.find(params[:id])
    @microphoto.update_attribute(:votes_up, @microphoto.votes_up + 1)
    redirect_to root_path
  end

  def vote_down
    @microphoto = Microphoto.find(params[:id])
    @microphoto.update_attribute(:votes_down, @microphoto.votes_down + 1)
    redirect_to root_path
  end

  # route
  resources :microphotos do
    collection do
     put '/vote_up/:id' => "microphotos#vote_up", :as => :vote_up
     put '/vote_down/:id' => "microphotos#vote_down", :as => :vote_down
    end
  end

解决方案2(用户不能多次投票)

如果您希望用户无法对微照片进行多次投票,您应该制作一个单独的模型,microphoto model进行投票,vote modelmicrophoto model有关系,关系如下:

class User < ActiveRecord::Base
has_many :vote_photos
has_many :microphotos
end

class Microphoto < ActiveRecord::Base
has_many :vote_photos
belongs_to :user
end

class VotePhoto < ActiveRecord::Base
 belongs_to :microphoto
 belongs_to :user
end