2013-03-19 4 views
1

J'ai trouvé une situation inhabituelle sur les rails 3 app.Rails has_many à travers?/vide?

Soit le modèle:

class Genre < ActiveRecord::Base 
    has_many :banner_genres, :dependent => :destroy 
    has_many :banners, :through => :banner_genres 
    ... 

class BannerGenre < ActiveRecord::Base 
    attr_accessible :banner_id, :banner, :genre_id, :genre, :position 

    belongs_to :genre 
    belongs_to :banner 
    ... 

class Banner < ActiveRecord::Base 
    has_many :banner_genres, :dependent => :destroy 
    has_many :genres, :through => :banner_genres 
    ... 

Maintenant, si j'ai un genre avec une bannière, je reçois les lignes suivantes dans la console Rails:

1.9.3p362 :005 > g = Genre.find 62 
    Genre Load (0.8ms) SELECT "genres".* FROM "genres" WHERE "genres"."id" = $1 LIMIT 1 [["id", 62]] 
=> #<Genre id: 62, ... 

1.9.3p362 :006 > g.banner_genres.any? 
    (0.5ms) SELECT COUNT(*) FROM "banner_genres" WHERE "banner_genres"."genre_id" = 62 
=> true 

1.9.3p362 :007 > g.banners 
    Banner Load (1.0ms) SELECT "banners".* FROM "banners" INNER JOIN "banner_genres" ON "banners"."id" = "banner_genres"."banner_id" WHERE "banner_genres"."genre_id" = 62 ORDER BY position 
=> [#<Banner id: 446, ... 

1.9.3p362 :008 > g.banners.any? 
=> false 

Pourquoi les .any? retours false? Je suis avec un autre à travers l'association sur le même projet et il renvoie true.

Edit:

J'ai eu une faute de frappe lors du passage du code ici. C'est banner_genres sur le has_many. Pas genre_banners.

également l'association inverse fonctionne comme il est censé:

1.9.3p362 :004 > b = Banner.find 446 
    Banner Load (1.1ms) SELECT "banners".* FROM "banners" WHERE "banners"."id" = $1 ORDER BY position LIMIT 1 [["id", 446]] 
=> #<Banner id: 446... 

1.9.3p362 :005 > b.genres.any? 
(0.8ms) SELECT COUNT(*) FROM "genres" INNER JOIN "banner_genres" ON "genres"."id" = "banner_genres"."genre_id" WHERE "banner_genres"."banner_id" = 446 
=> true 

Edit 2

Plus sortie étrange de la console:

1.9.3p362 :007 > g.banners.class 
=> Array 
1.9.3p362 :008 > g.banners.any? 
=> false 
1.9.3p362 :004 > g.banners.any? {|b| b} 
=> true 
1.9.3p362 :006 > g.banners.count 
(0.9ms) SELECT COUNT(*) FROM "banners" INNER JOIN "banner_genres" ON "banners"."id" = "banner_genres"."banner_id" WHERE "banner_genres"."genre_id" = 62 
=> 1 
1.9.3p362 :009 > g.banners.to_a.any? 
=> true 

Edit 3

g.banner_genres 
    BannerGenre Load (0.7ms) SELECT "banner_genres".* FROM "banner_genres" WHERE "banner_genres"."genre_id" = 62 
=> [#<BannerGenre id: 4, genre_id: 62, banner_id: 446, position: 1, created_at: "2013-03-15 16:41:10", updated_at: "2013-03-15 16:41:10">] 

Modifier 4 Posée par Aleks

pourriez-vous s'il vous plaît montrer les requêtes qui sont affichées sur g.banners.any? et g.banners. C'est exactement la même requête, ce qui est encore plus étrange. Je n'ai pas non plus outrepassé le any? méthode n'importe où.

1.9.3p362 :037 > g.banners(true) 
    Banner Load (1.0ms) SELECT "banners".* FROM "banners" INNER JOIN "banner_genres" ON "banners"."id" = "banner_genres"."banner_id" WHERE "banner_genres"."genre_id" = 62 ORDER BY position 
=> [#<Banner id: 446, ... 
1.9.3p362 :038 > g.banners(true).any? 
    Banner Load (1.2ms) SELECT "banners".* FROM "banners" INNER JOIN "banner_genres" ON "banners"."id" = "banner_genres"."banner_id" WHERE "banner_genres"."genre_id" = 62 ORDER BY position 
=> false 

1.9.3p362 :039 > g.banners.method(:any?) 
=> #<Method: Array(Enumerable)#any?> 
+4

Juste d'intérêt, est-il censé être 'has_many: genre_banners, has_many: bannières, : through =>: banner_genres'? Je m'attendais à ce que ': has_many' et': through' soient les mêmes. – omnikron

+2

pouvez-vous nous donner toutes les informations sur les associations sur ce modèle? Soit vous devez avoir ': through =>: genre_banners' ou vous ne fournissez pas assez d'informations – Zippie

+0

@Zippie, j'ai ajouté l'info des 2 autres modèles – dcarneiro

Répondre

1

La vraie question est pas là si l'association est bonne ou mauvaise, mais pourquoi il montre false pour le tableau qui a des éléments qu'il contient. Il est clair qu'il retourne des valeurs, mais la question est pourquoi il revient false

L'explication pourrait poser ici: Unable to get Ruby's #any? to return false with list of nil objects

Voyez comment le any? est mis en œuvre, et comment il se rapporte à votre question, pourrait vous donner un indice.

Voir ce lien ainsi: http://apidock.com/ruby/Enumerable/any%3F

EDIT:

Ce que vous dites: D'abord, vous avez un tableau de objects.Qui le any? retour false

Mais si vous le faites .to_a vous faites quelque chose comme ceci:

Time.new.to_a #=> [39, 54, 8, 9, 4, 2013, 3, 99, true, "CET"] 

Et c'est pourquoi il retournera true, que vous aurez l'objet qui ne sont pas nuls.

EDIT 2

Juste à noter: any? renverra false si tous les objets d'un tableau sont nil ou false

+0

avant qu'il a fait l'édition la vraie question était ce qui est avec les relations – Zippie

+0

ouh, alors ok. Merci de me le faire savoir. – Aleks

+0

@Aleks, mais aucun des éléments du tableau est nul. – dcarneiro

1

any? était censé revenir true .... J'étais si curieux ce problème que j'ai décidé de le simuler.

g = Genre.find 1 
Genre Load (30.1ms) SELECT "genres".* FROM "genres" WHERE "genres"."id" = $1 LIMIT 1 [["id", 1]] 
=> #<Genre id: 1, name: "a", created_at: "2013-03-19 11:44:32", updated_at: "2013-03-19 11:44:32"> 

g.banner_genres.any? 
(0.3ms) SELECT COUNT(*) FROM "banner_genres" WHERE "banner_genres"."genre_id" = 1 
=> true 

g.banners 
Banner Load (0.5ms) SELECT "banners".* FROM "banners" INNER JOIN "banner_genres" ON "banners"."id" = "banner_genres"."banner_id" WHERE "banner_genres"."genre_id" = 1 
=> [#<Banner id: 1, name: "1", created_at: "2013-03-19 11:43:00", updated_at: "2013-03-19 11:43:00">, #<Banner id: 2, name: "2", created_at: "2013-03-19 11:43:59", updated_at: "2013-03-19 11:43:59">] 

g.banners.any? 
=> true 

En outre,

g.banners.class 
=> Array 
g.banners.any? 
=> true 
g.banners.to_a.any? 
=> true 

Il y a quelque chose d'autre se passe dans votre code ...

+0

@gablielhilal, quelle version de ruby ​​/ rails avez-vous utilisée? – dcarneiro

+0

rails 3.2.12, ruby ​​1.9.3-p0 – gabrielhilal