0

私はHartlのチュートリアルを終了し、過去数日間、Twitterのような@repliesを追加しようとしても無駄になりました。特定のユーザーのIDを参照するために使用できると思われる整数としてin_reply_to列をMicropostsテーブルに追加しました。現在、私は正規表現を使用して、Micropostsコントローラーを介して特定のユーザーの名前と一致するものを検索しています。

Hartlは、Micropostモデルでincludeing_repliesスコープを使用することを提案しています。自動アソシエーションレールが作成するものや、私が伝えなければならないことに基づいて、このスコープに何を含めるべきかがよくわからないことを認めます。

どんな援助でも大歓迎です。

ユーザーモデル

  has_many :microposts, dependent: :destroy
  has_many :replies, through: :microposts, source: :in_reply_to

  VALID_NAME_REGEX =  /\A[\w+\-.]\z/i
  validates :name, presence: true,
            format: { with: VALID_NAME_REGEX },
            length: { maximum: 20 },
            uniqueness: { case_sensitive: false }

...

  def feed
    Micropost.from_users_followed_by(self)
    Micropost.including_replies
  end

マイクロポストモデル

class Micropost < ActiveRecord::Base
  attr_accessible :content
  belongs_to :user
  belongs_to :in_reply_to, class_name: "User"

  validates :user_id, presence: true
  validates :content, presence: true, length: { maximum: 140 }

  default_scope order: 'microposts.created_at DESC'
  scope :including_replies, where("user_id = in_reply_to")

  def self.from_users_followed_by(user)
    followed_user_ids = "SELECT followed_id FROM relationships
                         WHERE follower_id = :user_id"
    where("user_id IN (#{followed_user_ids}) OR user_id = :user_id",
          user_id: user.id)
  end
end

マイクロポストコントローラー

class MicropostsController < ApplicationController
  before_filter :signed_in_user, only: [:create, :destroy]
  before_filter :correct_user,   only: :destroy
  before_filter :reply_to_user, only: :create

  def create
    @micropost = current_user.microposts.build(params[:micropost])
      if @micropost.save
      flash[:success] = "Micropost created!"
      redirect_to root_path
    else
      @feed_items = []
      render 'static_pages/home'
    end
  end

  def destroy
    @micropost.destroy
    redirect_to root_path
  end

  private

    def correct_user
      @micropost = current_user.microposts.find_by_id(params[:id])
      redirect_to root_path if @micropost.nil?
    end

    def reply_to_user
      if reply_to = @micropost.content.match(/\A(@[\w+\-.])\z/i)
      @other_user = User.where(name: reply_to.to_s[1..-1])
        if @other_user && current_user.followed_users.includes(@other_user)
        @micropost.in_reply_to = @other_user.id
        end
      end
    end

end
4

1 に答える 1

0

私はこれを調べ始めましたが、最初に気付いたのは、返信を探している正規表現が機能しないことです。

> /\A(@[\w+\-.])\z/i.match("@someName blabla")
=> nil 

したがって、最初のヒント:実装しているすべてのビットをテストします。また、あなたは関連付けを間違えたと思います、私は使用しました

   has_many :replies, foreign_key: "to_id", class_name: "Micropost"

(下線を使用すると奇妙な非推奨の警告があったため、キーの名前をin_reply_toから単に「to」に変更しました)。

しかし、あなたは主にMicropostで新しいスコープを定義する方法を尋ねました。私はこのようにしました:

scope :from_users_followed_by_including_replies, lambda { |user| followed_by_including_replies(user) }

..。

def self.followed_by_including_replies(user)
  followed_ids = %(SELECT followed_id FROM relationships
                   WHERE follower_id = :user_id)
  where("user_id IN (#{followed_ids}) OR user_id = :user_id OR to_id = :user_id",
        { :user_id => user })
 end

それがお役に立てば幸いです。あなたは私の実装全体を見ることができます

https://github.com/htw-rails/TutorialSampleApp32/tree/reply

于 2012-07-11T20:10:59.213 に答える