Rails多个Has_one关系到同一模型



我正在开发一个Rails应用程序,目前我有2个模型-主题和课程。一门学科有三种不同类型的课程——讲座、辅导课和实验课。我这样建模,有3个has_1到教训模型。

现在,我正试图为主题和课程创建一个嵌套的形式,但讲座,教程和实验室被保存总是呈现的第一个形式。即我有3个嵌套的形式分别为讲座,教程和实验室,但讲座,教程和实验室保存的总是一个是第一次建立。在我的代码中,首先构建了lecture,因此tutorial和laboratory的属性将遵循我为lecture填写的属性。

我不确定我在哪里出了问题,或者即使在这种情况下有多个has_one关系工作,所以任何建议都会很感激。

相关代码如下:

主题模型

class Subject < ActiveRecord::Base
  has_one :lecture, :class_name => "Lesson"
  has_one :laboratory,:class_name => "Lesson"
  has_one :tutorial, :class_name => "Lesson"
  accepts_nested_attributes_for :lecture
  accepts_nested_attributes_for :laboratory
  accepts_nested_attributes_for :tutorial 
end

课程模型

class Lesson < ActiveRecord::Base
  belongs_to :subject
end

主题和课程嵌套形式

<%= form_for(@subject_list) do |f| %>
  <div class="field">
    <%= f.label :subject_code %><br />
    <%= f.text_field :subject_code %>
  </div>
  <div>
    <%= f.fields_for :lecture do |lecture| %>
      <%= render "lecture_fields", :f => lecture %>
    <% end %>
  </div>
  <div>
    <%= f.fields_for :tutorial do |tutorial| %>
      <%= render "tutorial_fields", :f => tutorial %>
    <% end %>
  </div>
  <div>
    <%= f.fields_for :laboratory do |laboratory| %>
      <%= render "laboratory_fields", :f => laboratory %>
    <% end %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

主题控制器中的新动作

    def new
    @subject = Subject.new
    lecture = @subject.build_lecture
    laboratory = @subject.build_laboratory
    tutorial = @subject.build_tutorial
    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @subject }
    end
  end
如果有人能帮我找出我哪里做错了,我会很感激的。如果在这种情况下,我不应该创建这样的多个关系,我想有一些建议,我如何才能实际呈现出3个表单与一个默认字段指示课程类型。

我不确定这是否有效,但我的建议是使用AR继承

class Lesson < ActiveRecord::Base
end
class LectureLesson < Lesson
  belongs_to :subject
end
class LaboratyLesson < Lesson
  belongs_to :subject
end
class TutorialLesson < Lesson
  belongs_to :subject
end
class Subject
  has_one :lecture_lesson
  has_one :laboratory_lesson
  has_one :tutorial_lesson
  accepts_nested_attributes_for :lecture_lesson
  accepts_nested_attributes_for :laboratory_lesson
  accepts_nested_attributes_for :tutorial_lesson
end
迁移

class LessonsAndSubjects < ActiveRecord::Migration
  def up
    remove_column :subjects, :lesson_id
    add_column :subjects, :lecture_lesson_id, :integer
    add_column :subjects, :laboratory_lesson_id, :integer
    add_column :subjects, :tutorial_lesson_id, :integer
    add_column :lessons, :type, :string
    add_index :subjects, :lecture_lesson_id
    add_index :subjects, :laboratory_lesson_id
    add_index :subjects, :tutorial_lesson_id
  end
  def down
    remove_column :subjects, :lecture_lesson_id
    remove_column :subjects, :laboratory_lesson_id
    remove_column :subjects, :tutorial_lesson_id
    remove_column :lessons, :type
    add_column :subjects, :lesson_id, :integer
  end
end

它更有意义,它可能会解决嵌套属性的问题

实际上,从答案来看,从错误中缺失了一点,您需要为每个"子"添加一个多态关联,以避免在查询中出现问题

class Lesson < ActiveRecord::Base
  belongs_to :subject
end
class LectureLesson < Lesson
  belongs_to :polymorphic_lecture_lesson, polymorphic: true
end
class Subject
  has_one :lesson
  has_one :lecture_lesson, as: :polymorphic_lecture_lesson
  accepts_nested_attributes_for :lesson
  accepts_nested_attributes_for :lecture_lesson
end

在迁移中,你必须添加

add_column :lessons, :polymorphic_lecture_lesson_id, :integer, index: true
add_column :lessons, :polymorphic_lecture_lesson_type, :integer, index: true

有趣的是,我对这个问题的解释与其他答案截然不同。

如果您希望在单个模型/表中有2个has_one,那么可以执行以下操作:

假设一个人有一个最好的宠物和一个最差的宠物,它们由相同的pet表/模型表示,该表/模型具有区分两者的属性…

class Person < ApplicationRecord
    has_one :best_pet, -> { where(pet_type: "best") }, class_name: "Pet"
    has_one :worst_pet, -> { where(pet_type: "worst") }, class_name: "Pet"
    ...
end
class Pet < ApplicationRecord
    belongs_to :person 
    validates_presence_of :pet_type
    validates_uniqueness_of :pet_type, scope: :person_id
    ...   
end

现在,这是否是一个好的数据库设计有待讨论。

相关内容

  • 没有找到相关文章

最新更新