1

我有一个简单的帖子和用户应用程序,用户可以在其中提交和支持帖子。我有两个模型,post 和 user,现在我正在使用 post 模型来添加“upvoting”功能。

每个帖子都有一个:id,:upvote:users_voted_by属性。每个用户都有一个:username,:posts_voted_ongood_karma属性

当用户点击帖子上的upvote按钮时,我需要确保当前用户不在:users_voted_by该帖子的列中,如果不在,则:upvote将该帖子的属性添加1。这部分完成了。

但我还需要将帖子添加:id到当前用户的:posts_voted_on字段中,并在提交者的:good_karma字段中添加 1。

岗位型号:

class Post < ActiveRecord::Base
  attr_accessible :comment_count, :downvote, :id, :text, :title, :upvote, :url, :user, :users_voted_by
end

用户型号:

class User < ActiveRecord::Base
  attr_accessible :email, :password, :password_confirmation, :username, :posts_voted_on, :good_karma, :bad_karma

  attr_accessor :password
  before_save :encrypt_password

  validates_confirmation_of :password
  validates_presence_of :password, :on => :create
  validates_presence_of :email
  validates_uniqueness_of :email
  validates_presence_of :username
  validates_uniqueness_of :username

  def self.authenticate(email, password)
    user = find_by_email(email)
    if user && user.password_hash == BCrypt::Engine.hash_secret(password, user.password_salt)
      user
    else
      nil
    end
  end

  def encrypt_password
    if password.present?
      self.password_salt = BCrypt::Engine.generate_salt
      self.password_hash = BCrypt::Engine.hash_secret(password, password_salt)
    end
  end
end

我的upvote方法在posts_controller中:

  def upvote
    @post = Post.find(params[:post_id])

    respond_to do |format|
      if @post.users_voted_by.index(current_user.username) == nil && @post.update_attributes(:upvote => @post.upvote + 1, :users_voted_by => @post.users_voted_by + ',' + current_user.username)
        format.html { redirect_to @post }
        format.json { head :no_content }
      else
        format.html { render action: "edit" }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

第五行是魔法所在。确保我投票的帖子没有该:users_voted_by领域的当前用户。然后它更新:upvote:users_voted_by字段。

如何添加到此方法(操作?),以便它还更新投票用户和帖子提交者的属性以存储业力的增加。

4

1 回答 1

1

猜测服务对象可以在这里提供帮助,例如(未测试)

class Voter
  def initialize(post, user)
    @post = post
    @user = user
  end

  def upvote
    return false unless @post.users_voted_by.index(@user.username)
    @post.upvote += 1
    @post.users_voted_by = @post.users_voted_by + ',' + @user.username
    @user.good_carma += 1
    @post.save && @user.save
  end

  def downvote
    ...
  end
end

然后控制器看起来像

   def upvote
    @post = Post.find(params[:post_id])
    respond_to do |format|
      if Voter.new(@post, current_user).upvote
        format.html { redirect_to @post }
        format.json { head :no_content }
      else
        format.html { render action: "edit" }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end
于 2013-01-10T07:05:51.727 回答