2013-01-10 46 views
1

我有一个简单的帖子和用户应用程序,用户提交和upvote帖子。我有两个模型,发布和用户,现在我正在使用发布模型添加“upvoting”功能。从其他模型的控制器更新一个模型的属性

每个帖子都有一个:id,:upvote:users_voted_by属性。当用户点击后在给予好评按钮 每个用户都有一个:username:posts_voted_ongood_karma属性

,我需要确保当前用户不是该讯息的:users_voted_by列,如果没有,加1到该帖子的:upvote属性。这部分完成了。

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

Post模型:

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 

我给予好评的方法是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字段。

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

回答

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 
+0

哪里的服务对象去了? – alt

+1

'app/services/voter.rb'。 'services'文件夹默认不存在,只需创建它即可。其实,你可以按照你的意愿命名。 – dimuch

+0

如何将它包含到我的应用程序中?我必须做额外的事情才能让Voter类工作吗? – alt