1

この投稿で多くのことを求めていることは承知していますが、Ruby/Rails に関する本を 4 冊読んだ後、「あはは」の瞬間が得られないという事実に不満を感じています。誰かが助けてくれるなら、私が来てあなたの朝食を作ります(1週間分)。

私は PHP/MySQL の世界から来ましたが、Rails の特定の事柄を理解するのが難しいと感じています。私が最後に読んだ Michael Hartl の本では、彼が本で作成したアプリケーションに追加する演習がいくつか提案されています。それは協会と関係があります。だから、私は本当に立ち往生しているので、誰かがこれについてのヒントを教えてくれるかどうか疑問に思っていました.

彼が構築するアプリケーションは、ほぼ Twitter のクローンです。マイクロポストを投稿するユーザーがいます。彼らのホームページは次のようになりますhttp://ruby.railstutorial.org/chapters/following-users#fig:home_page_with_feed ユーザー自身のマイクロポストは「フィード」の右側に投稿されます。フィード内のユーザーのマイクロポストに加えて、現在のユーザーがフォローしているユーザーによるマイクロポストもあります。任意のユーザーをフォローおよびフォロー解除できます。

この演習では、@replies を追加することを提案しています。@reply は、@username で始まるマイクロポストです (例: 「@mikeglaz お元気ですか」)。このマイクロポストは、あなたのフィードとユーザー名のフィードに表示されます (フォローしているユーザーとは限りません)。著者は次のように提案しています: 「これには、microposts テーブルに in_reply_to 列を追加し、Micropost モデルに追加の includes_replies スコープを追加する必要があるかもしれません。」しかし、他のユーザーをフォローすることに関する関連付けは非常に複雑で、これが私を行き詰まらせている原因です。私はいくつかのコードを投稿します:

ユーザー

class User < ActiveRecord::Base
  attr_accessible :email, :name, :password, :password_confirmation
  has_secure_password
  has_many :microposts, dependent: :destroy
  has_many :relationships, foreign_key: "follower_id", dependent: :destroy
  has_many :followed_users, through: :relationships, source: :followed
  has_many :reverse_relationships, foreign_key: "followed_id",
       class_name:  "Relationship",
       dependent:   :destroy
  has_many :followers, through: :reverse_relationships, source: :follower

  def feed
    Micropost.from_users_followed_by(self)
  end

  def follow!(other_user)
    relationships.create!(followed_id: other_user.id)
  end

  def unfollow!(other_user)
    relationships.find_by_followed_id(other_user.id).destroy
  end
end

end

関係

class Relationship < ActiveRecord::Base
  attr_accessible :followed_id

  belongs_to :follower, class_name: "User"
  belongs_to :followed, class_name: "User"
end

マイクロポスト

class Micropost < ActiveRecord::Base
  attr_accessible :content
  belongs_to :user

  def self.from_users_followed_by(user)
    followed_user_ids = user.followed_user_ids
    where("user_id IN (?) OR user_id = ?", followed_user_ids, user)
  end
end
4

4 に答える 4

0

ユーザー名を使用して人を見つけていることに注意してください....そして、@replyが機能するようにするコードを具体的に追加しました。Michael Hartl による rails チュートリアルは既に終了しているはずです。

データベース

class CreateRecipients < ActiveRecord::Migration
  def change
    create_table :recipients do |t|
      t.string :user_id
      t.string :micropost_id

      t.timestamps
    end
  end

  def self.down
    drop_table :recipients
  end
end

モデル

class Recipient < ActiveRecord::Base
  attr_accessible :micropost_id, :user_id

  belongs_to :user
  belongs_to :micropost

end


class Micropost < ActiveRecord::Base
  attr_accessible :content, :recipients
  belongs_to :user

  USERNAME_REGEX = /@\w+/i

  has_many :recipients, dependent: :destroy
  has_many :replied_users, :through => :recipients, :source => "user"

  scope :from_users_followed_by, lambda { |user| followed_by(user) }

  after_save :save_recipients

  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

  private

    def self.followed_by(user)
      followed_ids = %(SELECT followed_id FROM relationships
                    WHERE follower_id = :user_id)
      micropost_ids = %(SELECT micropost_id FROM recipients
                    WHERE user_id = :user_id)
      where("id IN (#{micropost_ids}) OR user_id IN (#{followed_ids}) OR user_id",
      {:user_id => user})
    end

    def save_recipients
      return unless reply?

      people_replied.each do |user|
        Recipient.create!(:micropost_id => self.id, :user_id => user.id)
      end
    end

    def reply?
      self.content.match( USERNAME_REGEX )
    end

    def people_replied
      users = []
      self.content.clone.gsub!( USERNAME_REGEX ).each do |username|
        user = User.find_by_username(username[1..-1])
        users << user if user
      end
      users.uniq
    end
end


class User < ActiveRecord::Base
  attr_accessible :name, :email, :password, :password_confirmation,
                  :username
  has_secure_password

  before_save { |user| user.email = email.downcase }
  before_save :create_remember_token

  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  VALID_UNAME_REGEX = /^[a-z](\w*[a-z0-9])*$/i

  has_many :micropost, dependent: :destroy

  has_many :relationships, foreign_key: "follower_id", dependent: :destroy
  has_many :followed_users, through: :relationships, source: :followed

  has_many :reverse_relationships, foreign_key: "followed_id",
                                   class_name:  "Relationship",
                                   dependent:   :destroy
  has_many :followers, through: :reverse_relationships, source: :follower

  has_many :replies, :class_name => 'Recipient', :dependent => :destroy
  has_many :received_replies, :through => :replies, :source => 'micropost'

  def to_param
    self.username
  end

end
于 2013-03-01T09:03:44.577 に答える
0

私のソリューションには、 has_many: 関連付けまたはスコープは含まれていませんでした。もっと粗雑かもしれませんが、うまくいくようです。

これは私がしたことです:

  1. user_nameユーザーに追加
  2. in_reply_toマイクロポストに追加
  3. コントローラーで正規表現を使用して、@user_name の新しい投稿をスキャンし、相関する user_id を選択します
  4. その user_id をマイクロポストのin_reply_to
  5. フィードの SQL クエリに追加してin_reply_to、ユーザーの ID と一致する投稿を選択します

私のレポはこちら: https://github.com/paul-ylz/sample_app

于 2013-10-20T13:26:47.913 に答える
0

うーん、具体的な質問は何ですか?ヒントとして、複雑な User アソシエーションを見る必要はありません! (私はそれらも混乱を招くように感じました.すべての後に続くとおよび続く.

必要に応じて、14 日前に追加した私のソリューションをのぞいてみてください。

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

  • このバージョンは Rails 3.0 バージョンのチュートリアルから離れているため、一部のソース コードは少し異なって見える場合があります。
于 2012-07-25T19:38:15.473 に答える