【问题标题】:Why doesn't this Ruby on Rails code work as I intend it to?为什么这个 Ruby on Rails 代码没有按我的预期工作?
【发布时间】:2011-03-19 08:03:58
【问题描述】:

所以我尝试构建我在这个问题中询问的内容:Fix voting mechanism

但是,此解决方案不起作用。用户仍然可以随意投票多次。我该如何解决这个问题和/或重构?

def create       
    @video = Video.find(params[:video_id])
    @vote = @video.video_votes.new
    @vote.user = current_user

    if params[:type] == "up"
      @vote.value = 1
    else
      @vote.value = -1
    end

  if @previous_vote.nil?
    if @vote.save
      respond_to do |format|
        format.html { redirect_to @video }
        format.js
      end
    else
      respond_to do |format|
        format.html { redirect_to @video }
        format.js {render 'fail_create.js.erb'}
      end
    end
  elsif @previous_vote.value == params[:type]
    @previous_vote.destroy
  else
    @previous_vote.destroy    
    if @vote.save
      respond_to do |format|
        format.html { redirect_to @video }
        format.js
      end
    else
      respond_to do |format|
        format.html { redirect_to @video }
        format.js {render 'fail_create.js.erb'}
      end
    end
  end
  @previous_vote = VideoVote.where(:video_id => params[:video_id], :user_id => current_user.id).first
end

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 activerecord voting


    【解决方案1】:

    @previous_vote 似乎在每个请求的开头都为零?

    我会亲自取消控制器中的所有逻辑,并将唯一性约束放在它们所属的模型或数据库级别。

    更新

    这可能充满了错误,但将其视为伪代码

    模型类似:

    class Video < ActiveRecord::Base
      has_many :votes
    end
    
    class Vote < ActiveRecord::Base
      belongs_to :user
      belongs_to :video
      validates_uniqueness_of :user_id, :scope => :video_id # only one vote per person per video
    end
    
    class User < ActiveRecord::Base
      has_many :votes
    end
    

    控制器:

    def create
      @video = Video.find(params[:video_id])
      @vote = current_user.votes.find_or_create_by_video_id(@video.id)
    
      # change this next block of code so you assign value to the vote based on whatever logic you need
      if you_need_to_do_anything_to_change_its_value
        @vote.value = :whatever
      end
    
      if @vote.save
        redirect_to @video
      else
        render :whatever_is_appropriate
      end
    end
    

    【讨论】:

    • nil 是什么原因?为什么要把它移到模型上?代码在模型中的外观如何?
    • 如果投票未通过验证,是否会静默失败?另外,验证什么时候运行?当我尝试将投票保存到数据库中时?
    • 如果投票失败 @vote.save 将返回 false @vote.save! 将引发异常。验证将在调用save 触发的事务期间运行。您可以在这里找到 ActiveRecord 的回调结构:api.rubyonrails.org/classes/ActiveRecord/Callbacks.html
    • 我对你的控制器代码有点困惑。这条线到底是什么:@vote = current_user.votes.find_or_create_by_video_id(@video.id)?我需要一个 if 语句吗?另外,如果是创建方法而不是更新方法,我该如何更改投票的值?
    • 我假设 current_user 当然是事先设置好的。该行是 ActiveRecord 提供的动态查找器。它将找到现有的投票或创建新的投票。然后后面的代码行可以在再次保存投票之前修改值。我在上面添加了评论。
    猜你喜欢
    • 1970-01-01
    • 2018-07-20
    • 2020-11-10
    • 2021-12-11
    • 1970-01-01
    • 1970-01-01
    • 2022-10-14
    • 2017-06-08
    • 1970-01-01
    相关资源
    最近更新 更多