通过同一模型的两个 has_many 关系
Posted
技术标签:
【中文标题】通过同一模型的两个 has_many 关系【英文标题】:Two has_many relationship through same model 【发布时间】:2016-12-21 00:32:24 【问题描述】:我遇到了一个我不知道如何解决的问题。
我有三个模型
老师 房间 小时我需要通过相同的模型关联它们。到目前为止,我有一个名为 schedules 的第四个模型,它有两个外键。 teacher_id 和 hour_id,效果很好,但是我还需要通过这个模型来关联房间。
这是我的代码:
teacher.rb
class Teacher < ApplicationRecord
scope :active, -> where(deleted_at: nil)
has_many :schedules, dependent: :destroy
has_many :lesson_hours, through: :schedules
has_many :teacher_courses, dependent: :destroy
has_many :courses, through: :teacher_courses
has_many :registrations
def check_associations
errors.add(:base, "Há matrículas cadastradas com esse professor. Por favor ajuste antes de deletar.") if self.registrations.active.count > 0
return errors.blank?
end
def delete!
if check_associations
self.deleted_at = Time.current
save!
return true
else
return false
end
end
end
room.rb
class Room < ApplicationRecord
scope :active, -> where(deleted_at: nil)
has_many :room_courses, dependent: :destroy
has_many :courses, through: :room_courses
has_many :registrations
def check_associations
errors.add(:base, "Há matrículas cadastradas com essa sala. Por favor ajuste antes de deletar.") if self.registrations.active.count > 0
return errors.blank?
end
def delete!
if check_associations
self.deleted_at = Time.current
save!
return true
else
return false
end
end
end
lesson_hour.rb
class LessonHour < ApplicationRecord
scope :active, -> where(deleted_at: nil)
has_many :schedules, dependent: :destroy
has_many :teachers, through: :schedules
has_many :registrations
def check_associations
errors.add(:base, "Há matrículas cadastradas nesse horário. Por favor ajuste antes de deletar.") if self.registrations.active.count > 0
return errors.blank?
end
def delete!
if check_associations
self.deleted_at = Time.current
save!
return true
else
return false
end
end
end
schedule.rb
class Schedule < ApplicationRecord
belongs_to :teacher
belongs_to :lesson_hour
end
所有这些关联都是通过 TeachersController 中的表单构建的
teachers_controller.rb
def set_lesson_days_and_hours
@lesson_days = LessonHour.select(:weekday)
.group(:weekday)
.order(:weekday)
.to_a
@lesson_hours =
@lesson_days.each do |ld|
@lesson_hours[ld.weekday] = LessonHour.active
.select(:id, :start_time)
.order(:start_time)
.where(weekday: ld.weekday)
end
end
def teacher_params
params
.require(:teacher)
.permit(:name, :address, :address_number, :address_complement,
:address_cep, :address_neighborhood, :city, :state, :birthdate,
:email, :cpf, :rg, :phone, :mobile, :started_date, :bank, :agency,
:account_number, :gender, lesson_hour_ids: [], course_ids: [])
end
将课程时间链接到教师的形式如下:
<div class="row teacher-schedule">
<h4>Disponibilidade</h4>
<% @lesson_days.each do |ld| %>
<div class="col-md-2 one-per-line teacher-schedule">
<span><strong><%= t(:"date.day_names")[ld.weekday] %></strong></span>
<%= f.collection_check_boxes(:lesson_hour_ids, @lesson_hours[ld.weekday], :id, :start_time) do |check_box| %>
<%= check_box.label class:"label-checkbox" do %>
<%= check_box.check_box + check_box.text.strftime("%H:%M") %>
<% end %>
<% end %>
</div>
<% end %>
</div>
那么,我的问题是,如何在日程模型中包含房间关联?
提前致谢
【问题讨论】:
【参考方案1】:当您需要添加两个 has_many 时,您需要指定 foreign_key 和 class_name 以便 rails 可以进行连接。
例子:
class TwoHasMany < ApplicationRecord
has_many :scheduled_teachers, foreign_key: :teacher_id, class_name: 'Schedule'
has_many :teachers, through: :scheduled_teachers
has_many :scheduled_lessons, foreign_key: :lesson_hour_id, class_name: 'Schedule'
has_many :lesson_hours, through: :scheduled_lessons
end
【讨论】:
很好,谢谢安德烈。但在我看来,我该如何管理它。我的观点是新老师的表格,我需要以相同的表格添加房间和课程时间。到目前为止,我只有一堂课时间。以上是关于通过同一模型的两个 has_many 关系的主要内容,如果未能解决你的问题,请参考以下文章
如何在同一模型中进行 has_many 和 has_one 关联?