1

ユーザーが投稿を送信して賛成する簡単な投稿とユーザーアプリがあります。私には投稿とユーザーの2つのモデルがあり、現在、投稿モデルを使用して「賛成」機能を追加しています。

各投稿には、、:idおよび:upvote属性:users_voted_byがあります。各ユーザーには、、:usernameおよび:posts_voted_on属性good_karmaがあります

ユーザーが投稿の賛成ボタンをクリックしたときに、現在のユーザーがその投稿の列に含まれていないことを確認する必要があります。含まれていない場合は、その投稿の属性に:users_voted_by1を追加します。:upvoteこの部分は完了です。

ただし: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

私の賛成メソッドは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

5行目は魔法のあるところです。私が投票している投稿に現在のユーザーが: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 に答える