【问题标题】:Twitter like following in RailsTwitter 喜欢在 Rails 中关注
【发布时间】:2016-07-12 01:11:42
【问题描述】:

我在我的应用程序中关注了这个tutorial to create Twitter like following,但是,我的关注不是互惠的,事实上,对方根本没有关注用户。我的两个主要模型是UserStock。用户应该能够“关注”股票,但股票永远不会关注用户。

models/user.rb

class User < ActiveRecord::Base

  has_many :stock_relationships
  has_many :stocks, through: :stock_relationships, source: :user

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable,
         :omniauthable, :omniauth_providers => [:facebook, :twitter, :linkedin, :google_oauth2]

   # stock following/unfollowing
   def follow_stock(stock)
     stock_relationships.create(stock_id: stock.id)
   end

   def unfollow_stock(stock)
     stock_relationships.find_by(stock_id: stock.id).destroy
   end

   def following_stock?(stock)
     stock_relationships.include?(stock.id)
   end

end

由于我的Stock 模型并不真正属于任何人,因此我在该模型中还没有任何东西:

models/stock.rb

class Stock < ActiveRecord::Base

end

为了跟踪 usersfollowing 股票,我创建了另一个名为 StockRelationships 的模型:

models/stock_relationship.rb

class StockRelationship < ActiveRecord::Base
  belongs_to :user
end

我从控制台开始分配一个用户:

user = User.find(1)

我遇到了麻烦,因为在使用 following_stock? 方法时这似乎不起作用。

我可以创建一个stock_relationship

pry(main)> user.follow_stock(stock)
   (0.2ms)  BEGIN
  SQL (2.2ms)  INSERT INTO "stock_relationships" ("stock_id", "user_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["stock_id", 2], ["user_id", 1], ["created_at", "2016-07-12 01:01:00.552580"], ["updated_at", "2016-07-12 01:01:00.552580"]]
   (2.5ms)  COMMIT
=> #<StockRelationship:0x007ff0b960ba60
 id: 3,
 user_id: 1,
 stock_id: 2,
 created_at: Tue, 12 Jul 2016 01:01:00 UTC +00:00,
 updated_at: Tue, 12 Jul 2016 01:01:00 UTC +00:00>

我可以unfollow一只股票:

[10] pry(main)> user.unfollow_stock(stock)
  StockRelationship Load (0.4ms)  SELECT  "stock_relationships".* FROM "stock_relationships" WHERE "stock_relationships"."user_id" = $1 AND "stock_relationships"."stock_id" = $2 LIMIT 1  [["user_id", 1], ["stock_id", 2]]
   (0.1ms)  BEGIN
  SQL (0.3ms)  DELETE FROM "stock_relationships" WHERE "stock_relationships"."id" = $1  [["id", 3]]
   (1.5ms)  COMMIT
=> #<StockRelationship:0x007ff0b9d36a60
 id: 3,
 user_id: 1,
 stock_id: 2,
 created_at: Tue, 12 Jul 2016 01:01:00 UTC +00:00,
 updated_at: Tue, 12 Jul 2016 01:01:00 UTC +00:00>

但是,当我检查用户是否实际上是 following 股票时,我遇到了问题:

[13] pry(main)> user.following_stock?(stock)
=> false

应该返回true,因为用户实际上正在关注股票:

[15] pry(main)> StockRelationship.all
  StockRelationship Load (0.4ms)  SELECT "stock_relationships".* FROM "stock_relationships"
=> [#<StockRelationship:0x007ff0bfa00408
  id: 2,
  user_id: 1,
  stock_id: 1,
  created_at: Tue, 12 Jul 2016 00:32:55 UTC +00:00,
  updated_at: Tue, 12 Jul 2016 00:32:55 UTC +00:00>,
 #<StockRelationship:0x007ff0bfa002c8
  id: 4,
  user_id: 1,
  stock_id: 2,
  created_at: Tue, 12 Jul 2016 01:04:06 UTC +00:00,
  updated_at: Tue, 12 Jul 2016 01:04:06 UTC +00:00>]

我是否错误地实现了include??我在模型中搞砸了什么吗?

提前致谢!

【问题讨论】:

    标签: ruby-on-rails ruby activerecord activemodel


    【解决方案1】:

    您的错误是数据类型比较问题。试试这个:

       def following_stock?(stock)
         # either use this
         stock_relationships.where(stock_id: stock.id).present?
         # OR
         stock_relationships.pluck(:stock_id).include?(stock.id)
       end
    

    【讨论】:

    • 所以,两个答案都有效,包括约翰的下面。哪一个在 DB 上效率更高?
    • stock_relationships.where(stock_id: stock.id).present?,前提是您已为 stock_id 列编制索引。
    • @oreoluwa 如果您只是测试存在性,.exists? 会更好。 ;)
    • 当用户关注多只股票时,另一个成为瓶颈
    • 真@coreyward。但我认为这种方法会缓存它,以防 OP 想要遍历记录。存在吗?没有
    【解决方案2】:

    我现在不在一台可以测试的计算机上,但是查看您的代码,我偷偷怀疑原因可能是您的 has_many 关系中的source 声明。

    在您的用户模型中,您有source: :user,我相信这会使关系在从关系的User 侧搜索时查找user_id 而不是stock_id

    您可能希望将其更改为 source: :stock,或者在您的情况下,由于模型名称和关系相同,您可以完全省略 source 声明。

    【讨论】:

    • 完全摆脱了source: :user,但仍然返回false,即使我用user.follow_stock(stock)关注另一只股票。
    • 我想我可能刚刚发现了另一个问题,在您的以下股票方法中,您在集合上调用 .include? 但仅传递一个 id,我认为您需要将整个对象传递为一个参数,或者在一个 id 数组上调用 include,所以也许将其更改为:stock_relationships.map(&amp;:stock_id).include?(stock.id)
    • 如果它更有效,请随意接受 oreoluwas 的答案,我目前无法测试,也没有我头脑中的知识,我就在这里帮助所以如果你让它工作那就太好了!虽然我会补充一点,以确保您会处理 source 问题,因为它可能会在将来的某个时候再次咬住您! :)
    猜你喜欢
    • 1970-01-01
    • 2011-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-20
    • 2014-09-21
    相关资源
    最近更新 更多