2016-07-12 2 views
0

Я следую вместе с этим tutorial to create Twitter like following в своем приложении, однако мое следующее не является взаимным, по сути, другая сторона не следует за пользователем вообще. Мои две основные модели: User и Stock. Пользователь должен иметь возможность «следить» за запасом, но запас никогда не следует за пользователем.Twitter как следующий в Rails

модели/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 модель на самом деле не принадлежит никому я не имею ничего в этой модели еще:

модели/stock.rb

class Stock < ActiveRecord::Base 

end 

Чтобы следить за users, которые following акции, я создал еще одну модель под названием StockRelationships:

модели/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 a запасы:

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

Который должен быть ret 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? неправильно? Я что-то испортил в своих моделях?

Заранее благодарен!

ответ

0

Ваша ошибка в проблеме сравнения типов данных. Попробуйте это:

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

Итак, оба ответа работают, в том числе Джон внизу. Какой из них более эффективен в БД? – Godzilla74

+0

'stock_relationships.where (stock_id: stock.id) .present ?, если вы указали свой столбец' stock_id'. – oreoluwa

+0

@oreoluwa Если вы только проверяете существование, '.exists?' Еще лучше. ;) – coreyward

0

У меня нет компьютера, в котором я могу проверить в этот самый момент, однако, глядя на ваш код, я получаю подозрительное подозрение, причиной может быть объявление source в вашем has_many через отношение.

В модели пользователя у вас есть source: :user что я считаю, что делает соотношение вид для user_id и не stock_id при поиске с User стороны отношения.

Возможно, вы захотите его поменять на source: :stock, или в вашем случае, так как имя модели и отношения одинаковы, вполне возможно, что вы полностью откажетесь от объявления source.

+0

Избавился 'источник:: user' в целом, по-прежнему возвращаются ложь, хотя, даже после того, как я следую за другой акции с' user.follow_stock (складочном) '. – Godzilla74

+0

Я думаю, что, возможно, я только что нашел другую проблему, в вашем следующем методе запаса, который вы вызываете '.include?' В коллекции, но передавая только идентификатор, я думаю, вам нужно либо передать весь объект в качестве параметра, либо позвонить включите в массив идентификаторов, поэтому, возможно, измените его на: 'stock_relationships.map (&: stock_id) .include? (stock.id)' –

+1

не стесняйтесь принимать oreoluwas ответ, если он более эффективен, я не в чтобы проверить, что есть на данный момент, и у меня нет знаний с головы, я просто здесь, чтобы помочь, если вы получите его работу, это здорово! Хотя я просто добавлю, чтобы быть уверенным, что вы позаботитесь об этой проблеме «источника», которая может вернуться, чтобы укусить вас в какой-то момент в будущем! :) –