Can' t получают Array' s метод счета работать с блоком

У меня есть приложение Рельсов, которое содержит Тимсисона образцовый класс. Этот класс имеет has_one связь с Команда образцовый класс, и has_many ассоциация к другому , Тимсисон названный противников . Я теперь пытаюсь написать метод, который проходит в Команда и определяет, связан ли какой-либо из его противников с тем Команда . Метод, который я написал, выглядит примерно так:

def plays?(against_team)
  total = opponents.count {|opponent| opponent.team == against_team}
  return (total > 0)
end

количество метод должен посчитать количество элементов матрицы, которые приводят к истинному значению с блоком, который я определил. Однако кажется, что это всегда возвращает полное из множества. Это - как будто блок, который я определял всегда, приводит к истинному значению, несмотря ни на что.

Я добавил различный , помещает звонит, чтобы попытаться выяснить, где моя логика идет не так, как надо. Вот мои наблюдения:

  • , Когда я добавляю любой , помещает требования в блоке рядом с методом счета, я не вижу продукции для тех заявлений. Кажется, что содержание блока никогда не выполняется

  • , Когда я вставляю дополнительную петлю, используя множество противников каждый метод и блок, я могу напечатать ценность своих объектов множества и подтвердить, что они, оценивают, как я ожидаю. Я могу даже , помещает ценность opponent.team == against_team , и проверьте, что блок, который я написал, оценивает, чтобы ложный часть времени, как это должно.

Что я пропускаю здесь?

1
nl ja de
@jvnill: нет никакого team_id область в team_seasons столе, как it' s has_one отношения. Скорее стол команд имеет team_season_id область.
добавлено автор PinnyM, источник
Я can' t выясняют what' s неправильно с вашим кодом. Но можно осуществить метод, не используя количество. opponents.where (team_id: against_team.id) .exists?
добавлено автор jvnill, источник
вы правы. это должно быть opponents.joins (: команда) .where (команды: {id: against_team.id}) .exists? точно так же, как один из ответов, но команды должны быть множественным числом.
добавлено автор jvnill, источник

2 ответы

opponents is not a standard ruby Array - it's an ActiveRecord association proxy and behaves differently for certain methods. count will query the database for the number of opponents, and the block you are passing will not be evaluated. A simpler way to do what you want is like so:

def plays?(against_team)
  opponents.joins(:team).where(teams: {id: against_team.id}).exists?
end

Это спросит базу данных, что вы хотите и стараетесь не загружать всех противников, когда вы только проверяете на определенный матч. Альтернативно, можно ли загрузить всех противников, перечисляют и используют кого-либо? :

def plays?(against_team)
  opponents.any?{|opponent| opponent.team == against_team.id}
end

Обратите внимание, что это не только загрузит всех противников, но это загрузит команду каждого противника по одному - приводящий к вопросу N+1 (который приводит к исполнительным проблемам). Можно избежать, чтобы это нетерпеливой погрузкой связанной команды, использующей, <закодировало>, включает() :

opponents.includes(:team).any?{...}
3
добавлено
@jvnill: После испытания этого кажется, что вы правильны - обновленный.
добавлено автор PinnyM, источник
как я сказал в своем комментарии, я думаю, что ваш первый код должен использовать команды и не команда или используют где (' teams.id =? ' against_team.id)
добавлено автор jvnill, источник
@PinnyM: I' m вполне уверенный это вызовет некоторую ошибку. просто попробованный это на MySQL и pg и на has_one и belongs_to ассоциации.
добавлено автор jvnill, источник
Огромное спасибо за разъяснение. Я don' t думают, что я когда-либо выяснял бы это противники wasn' t стандарт множество Руби здесь. I' ve просто попробовал оба из ваших вариантов, и они оба работали на меня. Теперь, когда я знаю то, что продолжается, я могу выглядеть более глубоким то, как я буду использовать это, чтобы определить, какой подход будет работать лучше всего на меня.
добавлено автор Tim Dean, источник

Функциональность, которую вы пробуете, может быть достигнута, используя включать? метод.

Попытка:

def plays?(against_team)
  opponents.collect(&:team).include?(against_team)
end
0
добавлено
Используя собираются приведет к вопросам N+1, не большим, если у вас будет много противников...
добавлено автор PinnyM, источник
Я понимаю его.. @PinnyM ваше решение намного более эффективен..
добавлено автор Gaurav Agarwal, источник
Мне что включать кажется? метод только был бы применим, если бы я непосредственно проверял объект команды, переданный в мой метод для включения во множество противников. Однако это не то, что я пытаюсь проверить. Вместо этого я пытаюсь найти наш, если объект команды, передаваемый в, связан с каким-либо из противников через его ассоциацию команды. Таким образом, мне нужно что-то с выражением блока, чтобы оценить.
добавлено автор Tim Dean, источник
pro.ruby
pro.ruby
1 181 участник(ов)

Язык программирования Ruby Additional docs: https://rubyreferences.github.io/rubyref/ Invite: https://telegram.me/joinchat/Be4rsT2NuB3CyJaF26j1kA Кто хочет компилировать: @crystal_ru (его синтаксис основан на Ruby) Участник @proDOT

Ruby, Rails, Hanami | dry-rb
Ruby, Rails, Hanami | dry-rb
1 180 участник(ов)

https://telegram.me/rubyjob - Ruby Job По вопросам - @eugene_shved

Ruby School .us
Ruby School .us
1 045 участник(ов)

Чат-болталка для учеников руби-школы и не только. Правила: https://telegra.ph/Pravila-chata-Rubi-shkoly-03-13

Random Ruby Chat
Random Ruby Chat
589 участник(ов)

Правила публикации вакансий: https://t.me/codenamecrud/60865

Rubyata
Rubyata
333 участник(ов)

Коммюнити Ruby и Ruby On Rails Флуд не приветствуются. Вакансии можно публиковать только и ТОЛЬКО по пятницам с хештегом #вакансия.

Ruby Talks
Ruby Talks
236 участник(ов)

Национальная Флеймотека

RubyRush
RubyRush
189 участник(ов)

rubyrush.ru программирование для самых новичков

Rails Chat
Rails Chat
87 участник(ов)

You are welcome to discuss Ruby On Rails development process and other stuff