NoMethodError - неопределенный метод `loaner_individuals 'для # - PullRequest
0 голосов
/ 22 октября 2018

Я не могу понять, почему это не работает

Модели

class CompanyBorrower < ApplicationRecord
    has_many :borrower_individuals
    has_many :individuals, -> { distinct }, :through => :borrower_individuals
end

class BorrowerIndividual < ApplicationRecord
    belongs_to :company_borrower, optional: true
    belongs_to :individual, optional: true
end

class Individual < ApplicationRecord
    has_many :borrower_individuals
    has_many :company_borrowers, :through => :borrower_individuals
end

Контроллер

@borrower = CompanyBorrower.find(params[:id])
@individuals = @borrower.individuals.all
@roles = @individuals.borrower_individuals.all

И я получаю ошибку ...

undefined method `borrower_individuals' for #<Individual::ActiveRecord_AssociationRelation:0x000000000dc58660>

Ошибка происходит на @roles - если я удаляю, ошибка исчезает

Ответы [ 2 ]

0 голосов
/ 22 октября 2018
@borrower = CompanyBorrower.find(params[:id])
@individuals = @borrower.individuals.all
@roles = @individuals.borrower_individuals.all

Здесь Вы вызываете метод ассоциации на объект ActiveRecordRelation не на объект Active Record .ie Вы вызываете его при сборе ActiveRecords, а не в одной записи. Вам нужновызвать метод ассоциации на одной записи.@individuals = @ loaner.individuals.all

Здесь вы вызвали индивидуумы (метод ассоциации) для одного активного объекта записи (@borrower). Он вернет коллекцию ActiveRecords (объект ActiveRecord_Relation), если записи присутствуют (еслизаписей нет, будет возвращен пустой объект отношения активной записи).В следующей строке вы пытаетесь вызвать заемщик_individuals (метод связи) для объекта отношения записи Rectiveing. Поэтому он выдает ошибку

@roles = @individuals.borrower_individuals.all

, вам нужно переписать код выше

@roles = @individuals.map(&:borrower_individuals).flatten

Как упоминал Марек Липка, это вызовет N + 1 запрос и вернет объект массива.Чтобы избежать запроса N + 1, мы можем изменить его

@borrower = CompanyBorrower.find(params[:id])
@individuals = @borrower.individuals.all
@roles = @individuals.borrower_individuals.all

@borrower = CompanyBorrower.includes(individuals: [:borrower_individuals]).find(params[:id])
@individuals = @borrower.individuals.all
@roles = @individuals.map(&:borrower_individuals).flatten # will return array object.

, вы можете избежать переменных @individuals и @roles, если собираетесь использовать его на html-странице. Это зависит от того, как вы собираетесьиспользуйте это

0 голосов
/ 22 октября 2018

@individual не содержит одного Individual экземпляра, вместо этого он содержит Relation, для которого вы, очевидно, не можете вызывать Individual методы экземпляра.Вы можете установить @roles немного по-другому, например:

@roles = BorrowerIndividual.where(individual_id: @individuals.pluck(:id))

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...