联接中没有这样的属性列 table

No such column for attribute in a join table

我正在尝试创建一个应用程序,用户可以在其中选择志愿者来完成他们的任务。 volunteers 被视为 participants 的方式是通过放置在 TaskVolunteer 连接 table 上的 selected 布尔属性。不幸的是,当我试图找到特定 class 的参与者时,出现以下错误:

task = Task.create
task.participants
SQLite3::SQLException: no such column: users.selected

型号

class User < ActiveRecord::Base
  has_many :owned_tasks, class_name: "Task", foreign_key: :owner_id
  has_many :task_volunteers, as: :volunteer
  has_many :volunteered_tasks, through: :task_volunteers
end

class TaskVolunteer < ActiveRecord::Base
    # task_id, volunteer_id, selected (boolean)
    belongs_to :task
    belongs_to :volunteer, class_name: "User", foreign_key: :volunteer_id
end

class Task < ActiveRecord::Base
    # owner_id
    has_many :task_volunteers
    has_many :volunteers, through: :task_volunteers, source: :volunteer
    has_many :participants, -> {where(selected: true)}, through: :task_volunteers, source: :volunteer

    belongs_to :owner, class_name: "User"
end

错误是由 TaskVolunteer 中的错误 foreign_key 选项引起的。

 belongs_to :volunteer, class_name: "User", foreign_key: :volunteer_id
这里的

foreign_key是指users上的栏目,table不是tasks_volunteers上的栏目。您可以只删除外键选项。

class TaskVolunteer < ActiveRecord::Base
    # task_id, volunteer_id, selected (boolean)
    belongs_to :task
    belongs_to :volunteer, class_name: "User"
end

已添加

我不得不说,通过稍微改变命名并使用枚举来表示状态,您可以大大减少代码和认知复杂性。

class User < ActiveRecord::Base
  has_many :participations, foreign_key: :participant_id
  has_many :owned_tasks, class_name: "Task", as: :owner
end

class Task < ActiveRecord::Base
  belongs_to :owner, class_name: 'User'
  has_many :participations
  has_many :participants, through: :participations, source: :participant
  # Dynamically generates relations such as 'selected_participants'
  Participation.statuses.keys.each do |status|
    has_many "#{status}_participants".to_sym,
             -> { where(participations: { status: status.to_sym }) },
             through: :participations,
             source: :participant
  end
end

class Participation < ActiveRecord::Base
  belongs_to :task
  belongs_to :participant, class_name: "User"
  enum status: [:interested, :selected]
end

枚举宏为您提供如下内容:

user.participations.selected
participation.selected?