Rails“ActiveRecord_Associations_CollectionProxy的undefined method”

10

我有这些模型:

class Student < ActiveRecord::Base

    has_many :tickets
    has_many :movies, through: :tickets

end


class Movie < ActiveRecord::Base

    has_many :tickets, dependent: :destroy
    has_many :students, through: :tickets
    belongs_to :cinema

end


class Ticket < ActiveRecord::Base

    belongs_to :movie, counter_cache: true
    belongs_to :student

end


class Cinema < ActiveRecord::Base

    has_many :movies, dependent: :destroy
    has_many :students, through: :movies

    has_many :schools, dependent: :destroy
    has_many :companies, through: :yard_companies

end


class School < ActiveRecord::Base 

    belongs_to :company
    belongs_to :student
    belongs_to :cinema, counter_cache: true

end


class Teacher < ActiveRecord::Base

    belongs_to :movie, counter_cache: true
    belongs_to :company

end


class Contract < ActiveRecord::Base

    belongs_to :company
    belongs_to :student

end


class Company < ActiveRecord::Base

    has_many :teachers
    has_many :movies, through: :teachers

    has_many :contracts
    has_many :students, through: :contracts

end

如果我在我的 movies_controller.rb 文件中写下以下代码:

@students = @movie.cinema.companies.students.all

我会遇到以下错误信息:

undefined method 'students' for #Company::ActiveRecord_Associations_CollectionProxy:0x00000007f13d88>

如果我改为这样写:

@students = @movie.cinema.companies.find(6).students.all

它就能正确显示我所需的选定公司中的学生。

如何更好地理解这个过程?

更新:

我需要在电影院里对于每个公司的学生进行选集选择。

应该怎么写?

2个回答

8

根据Nermin的描述,您正在尝试从子集合中请求一组子项。

您可以使用collect方法按以下方式收集公司学生:

@movie.cinema.companies.collect(&:students).flatten.uniq

但我认为您最好在学生模型中添加范围,类似于:

scope :for_companies, ->(_companies) {joins(:companies).where(company: _companies)}

使用Student.for_companies(@movie.cinema.companies)调用

免责声明:未经测试,但应该是一个起点!


我正在尝试,@Matt。感谢您宝贵的回答。但是在第一种解决方案的collection_select中如何检索列表?我正在使用以下代码:<%= f.collection_select(:student_id, @students, :id, :name_with_surname, options = {:include_blank => true, :prompt => true}) %> - user4412054
@JohnSam 看起来不错,但是你是如何填充 @students 变量的呢? - Matt
使用以下代码 @students = @movie.cinema.companies.collect(&:students)movies_controllerdef new 方法中,如何填充集合以解决 .collect 方法的问题? - user4412054
@JohnSam,你应该选择我建议的第二个选项,走作用域的路线。这样更加简洁高效。 - Matt
无论如何都不起作用:他说:“students.company列不存在”。 - user4412054
显示剩余10条评论

6

@students = @movie.cinema.companies.students.all 这段代码会抛出错误。

@movie.cinema 将返回电影所在的电影院。

@movie.cinema.companies 将以 ActiveRecord_Association_CollectionProxy 的形式返回该电影院的公司列表。

但是,当您通过 @movie.cinema.companies.students 在公司的 CollectionProxy 上调用 students 时,会出现错误,因为 CollectionProxy 没有这样的方法。

@students = @movie.cinema.companies.find(6).students.all 是可行的,因为您可以获取公司列表,然后从列表中找到一个 ID 为 6 的公司,并列出该公司所有的学生。


4
可能需要一些“collect”示例,以实际获取来自多个公司集合中的所有学生。 - Matt
1
我需要在这部电影的公司中,每个学生的collection_select。如何编写? - user4412054

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接