Арель запрос через ассоциацию - PullRequest
1 голос
/ 27 апреля 2011

Вот мои модели:

class Player < ActiveRecord::Base
  has_many :registrations, :class_name => "PlayerRegistration"
end

class PlayerRegistration < ActiveRecord::Base
   belongs_to :player

   belongs_to :payment

   def self.paid
     where("payment_id IS NOT NULL")
   end

   def self.unpaid
     where(:payment_id => nil)
   end
end

class Payment < ActiveRecord::Base
  has_many :registrations, :class_name => "PlayerRegistration"
end

Что я хотел бы сделать, это создать область на Игроке, которая возвращает всех игроков, у которых есть неоплаченная регистрация, что-то вроде:

BADКОД PSUEDO ВПЕРЕД

class Player < ActiveRecord::Base

  def self.paid
    registrations.unpaid  #But actually return the players
  end
end

Возможно ли это?Должно быть, учитывая, что все необходимые мне данные есть, я просто не знаю, как написать такой запрос AREL.Кто-нибудь может помочь?

FWIW Я пробовал это:

class Player < ActiveRecord::Base
  def self.paid
    includes(:registrations).where("registrations.payment_id IS NOT NULL")
  end
end

, но это дает мне следующую ошибку:

ActiveRecord::StatementInvalid:
   PGError: ERROR:  missing FROM-clause entry for table "registrations"
   LINE 1: ...registrations"."player_id" = "players"."id" WHERE "registrat...
                                                                ^
   : SELECT "players"."id" AS t0_r0, "players"."first_name" AS t0_r1, "players"."last_name" AS t0_r2, "players"."birthday" AS t0_r3, "players"."gender" AS t0_r4, "players"."created_at" AS t0_r5, "players"."updated_at" AS t0_r6, "players"."user_id" AS t0_r7, "player_registrations"."id" AS t1_r0, "player_registrations"."player_id" AS t1_r1, "player_registrations"."grade_id" AS t1_r2, "player_registrations"."shirt_size_id" AS t1_r3, "player_registrations"."division_id" AS t1_r4, "player_registrations"."coach_request" AS t1_r5, "player_registrations"."buddy_request" AS t1_r6, "player_registrations"."created_at" AS t1_r7, "player_registrations"."updated_at" AS t1_r8, "player_registrations"."league_id" AS t1_r9, "player_registrations"."season_id" AS t1_r10, "player_registrations"."school_id" AS t1_r11, "player_registrations"."payment_id" AS t1_r12 FROM "players" LEFT OUTER JOIN "player_registrations" ON "player_registrations"."player_id" = "players"."id" WHERE "registrations"."payment_id" IS NULL

Может ли кто-нибудь показать мне лучшепуть?Разве я не могу использовать платную область, которая уже есть в PlayerRegistrations?

Ответы [ 2 ]

4 голосов
/ 27 апреля 2011

Вам нужно настоящее имя таблицы в фильтре where ():

class Player < ActiveRecord::Base
  def self.paid
    includes(:registrations).where("player_registrations.payment_id IS NOT NULL")
  end
end
1 голос
/ 28 апреля 2011

Вы можете написать:

class Player

  scope :unpaid, includes(:registrations).where("player_registrations.payment_id is null")
  scope :paid, includes(:registrations).where("player_registrations.payment_id is not null")

end

и теперь Player.unpaid вернет всех игроков с неоплаченными регистрациями.

Если вы напишите что-то вроде:

class Registration

  scope :paid, where("payment_id IS NOT NULL")
  scope :unpaid, where("payment_id is null")

end

тогда можно написать player1.registrations.unpaid, но это не то, что вы хотите. Если я правильно понимаю, вы хотите найти всех игроков с неоплаченными регистрациями, и это возможно только с помощью области действия Player класса.

Надеюсь, это поможет.

...