2013-03-19 3 views
1

Я нашел необычную ситуацию на рейках 3 приложения.Rails has_many через любой?/пусто?

Рассмотрим следующую модель:

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 
    ... 

Теперь, если у меня есть жанр с баннером, я получаю следующие строки в рельсах консоли:

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 

Почему .any? возвращается false? Я твой с другим has_many через ассоциацию в том же проекте, и он возвращает true.

Edit:

Я была опечатка при передаче кода здесь. Это banner_genres на has_many. Не genre_banners.

Кроме того, обратная связь работает, как это предполагается:

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

Более странно консольный вывод:

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 

Редактировать 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">] 

Edit 4 Спросивший Aleks

могли бы вы показать запросы, которые показаны на g.banners.any? и g.banners. Это точно такой же запрос, который еще более странный. Я тоже не отменял никого? метод в любом месте.

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

Просто из интереса, как это должно быть 'has_many: genre_banners, has_many: баннеры, : через =>: banner_genres'? Я ожидал, что ': has_many' и': through' будут одинаковыми. – omnikron

+2

можете ли вы предоставить нам всю информацию об ассоциациях на этой модели? Либо вы должны иметь ': through =>: genre_banners', либо не располагаете достаточной информацией – Zippie

+0

@ Zippie, я добавил информацию от других 2 моделей – dcarneiro

ответ

1

Реальный вопрос здесь не в том, хорошо или плохо ассоциации, но почему он показывает false для массива, который имеет элементы в нем. Понятно, что она возвращается значения, но вопрос в том, почему она возвращается false

Объяснение может лежать здесь: Unable to get Ruby's #any? to return false with list of nil objects

Посмотрите, как any? реализуется, и как он относится к вашему вопросу, это может дать вам подсказку.

Смотрите эту ссылку, а: http://apidock.com/ruby/Enumerable/any%3F

EDIT:

То, что вы говорите: Во-первых у вас есть массив objects.Что будет на any? возвращения false

Но если вы .to_a вы будете делать что-то вроде этого:

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

И именно поэтому он будет возвращать true, как вы будете иметь объект, которые не являются пустым.

EDIT 2

Просто к сведению: any? возвратит false, если все объекты из массива являются nil или false

+0

, прежде чем он сделал редактирование, реальный вопрос был в том, что связано с отношениями – Zippie

+0

ouh, тогда хорошо. Спасибо, что дали мне знать. – Aleks

+0

@Aleks, но ни один из элементов массива не равен нулю. – dcarneiro

1

any? должен был вернуться true .... Я был так интересно этот вопрос, который я решил имитировать.

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 

Кроме того,

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

Существует что-то еще происходит в вашем коде ...

+0

@ gablielhilal, какую версию рубинов/рельсов вы использовали? – dcarneiro

+0

рельсы 3.2.12, рубин 1.9.3-p0 – gabrielhilal

Смежные вопросы