我有一个简单的帖子和用户应用,用户提交和提交帖子。我有两个模型,帖子和用户,现在我正在使用帖子模型添加“upvoting”功能。
每个帖子都有:id
,:upvote
和:users_voted_by
属性。
每个用户都有:username
,:posts_voted_on
和good_karma
属性
当用户点击帖子上的upvote按钮时,我需要确保当前用户不在该帖子的:users_voted_by
列中,如果没有,请在:upvote
属性中添加1那篇文章。这部分已经完成。
但我还需要将帖子:id
添加到当前用户的:posts_voted_on
字段中,并将1添加到提交者的:good_karma
字段。
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
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
字段。
如何添加此方法(操作?),以便它还更新投票用户和帖子提交者的属性,以存储业力增长。
答案 0 :(得分:1)
猜猜service object可以在这里提供帮助,例如(未经测试)
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