Область Rails с вложенной ассоциацией

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

class Client
  has_many :referrals, through: :submissions
  has_one :address
  has_many :submissions
end

class Submission
    belongs_to :client
    belongs_to :user
    has_many :referrals, :inverse_of => :submission, dependent: :delete_all
end

class Referral
    belongs_to :branch
    belongs_to :submission
    has_one :client, through: :submission
end

class Address
    belongs_to :client
end

У меня также есть пользователи, созданные с помощью devise. У меня есть настраиваемый атрибут, добавленный для пользователей, который называется city_town.

Когда пользователь регистрируется, он выбирает, из какого он города или населенного пункта и агентство, в котором он работает. Когда представления создаются, они принимают вложенные атрибуты для сведений о клиенте и адресе, а также сведения о реферале. рефералы принимают Agency_id, который указывает, куда направляется этот реферал.

Чего я пытаюсь добиться, так это создать область, которая будет собирать все рефералы, где referral.client.address.city_town соответствует городу или городу текущего пользователя, то есть: current_user.city_town, а Agency_id реферала соответствует Agency_id вошедшего в систему пользователя.

Короче говоря, когда пользователь входит в систему, он может видеть рефералов только для своего агентства и региона.

Пока у меня есть:

class Referral
  scope :agency_referrals, -> (id, city_town) { includes(:clients).where(agency_id: id, client.address.city_town => city_town) }
end

но я с болью осознаю, что это далеко не правильно. Я получаю эту ошибку:

undefined local variable or method `client' for #<Class:0x00000003200c08>

Есть идеи, где я ошибаюсь?


person Craig    schedule 17.02.2016    source источник
comment
В какой модели у вас такой прицел?   -  person Pavan    schedule 17.02.2016
comment
В реферальном классе. Я отредактировал свой вопрос, чтобы показать это.   -  person Craig    schedule 17.02.2016
comment
Попробуйте includes(:client) вместо includes(:clients)   -  person Pavan    schedule 17.02.2016
comment
Я все еще получаю аналогичную ошибку с клиентом вместо клиентов.   -  person Craig    schedule 17.02.2016
comment
stackoverflow.com/questions/19175084/   -  person Ilya    schedule 17.02.2016
comment
Спасибо за ваш ответ @Ilya, но я хочу добиться этого с помощью областей.   -  person Craig    schedule 17.02.2016
comment
Крейг, интересно, может ли использоваться делегат (. Проверьте: stackoverflow.com/a/14893450/1461972). Может быть, вы можете иметь delegate :client, to: :submission вместо has_one :client, through: :submission?   -  person MrWater    schedule 25.02.2017


Ответы (2)


Вы получаете эту конкретную ошибку, потому что вы неправильно ссылаетесь на city_town в своем запросе. client.address.city_town => city_town будет означать, что ключ в этом хэше является значением, вложенным в существующую переменную «клиент». Это более правильно и, вероятно, устранит конкретную ошибку, с которой вы только что столкнулись:

Кстати, комментатор Паван был прав, :client должно стоять в единственном числе в вашем утверждении .includes(). Тем не менее, я также расширил его, включив таблицу адресов впереди, что могло вызвать дополнительные ошибки.

# The .includes() parameters have been changed, and quotes have been added to the query.
scope :agency_referrals, -> (id, city_town) { includes(client: :address).where(agency_id: id, 'client.address.city_town' => city_town) }

Кроме того, если вы ищете нестроковый метод ссылки на правильное местоположение (потому что это Ruby, и мы любим наши символы), вы можете написать это:

includes(:clients).where(agency_id: id, client: { address: { city_town: city_town } } => city_town)

Я лично нахожу это менее чистым, но это более «современный» формат.

Для получения дополнительной информации вы можете просмотреть эту документацию.

person ConnorCMcKee    schedule 17.02.2016
comment
Извините за задержку с ответом. Я попробую это и дам вам знать, как это происходит - person Craig; 18.02.2016

не могли бы вы попробовать

includes(submission: :clients)
person Marcel    schedule 17.02.2016
comment
Затем спрашивающему придется изменить свою ссылку на submit.client.address.city_town и ввести в смесь совершенно ненужную таблицу. - person ConnorCMcKee; 17.02.2016