【问题标题】:Rails: many to many relationship - creating and associating new recordsRails:多对多关系 - 创建和关联新记录
【发布时间】:2017-10-11 22:06:00
【问题描述】:

我正在看这个railscast #17 revised 作为使用连接表在两个模型之间创建多对多关系的教程:

class Course < ActiveRecord::Base
has_many :courselocalizations
has_many :courselocations, through: :courselocalizations
end

class Courselocation < ActiveRecord::Base
has_many :courselocalizations
has_many :courses, through: :courselocalizations
end

class Courselocalization < ActiveRecord::Base
belongs_to :course
belongs_to :courselocation
end

如果用户在编辑或创建course 时没有看到现有的courselocation,那么他们创建新的courselocation 并自动建立关联的最佳方法是什么?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4 many-to-many has-many-through


    【解决方案1】:

    您可以分两步进行(我的首选方法),也可以一步完成。

    两步流程: - 创建CourseLocation - 关联CourseLocationCourse

    course_location1 = CourseLocation.create(name: 'location1')
    course.course_locations << course_location1
    


    如果您想一步完成,可以使用 Active Record accepts_nested_attributes_for method,这有点棘手。这是一个good article,但让我们分解步骤:

    1. 课程需要接受 course_localizations 的属性
    2. 课程本地化需要接受 course_location 的属性
    3. 创建课程时,传递包含位置属性的本地化属性。

    让我们为您的特殊情况设置所有这些:

    class Course < ActiveRecord::Base
      # attribute subject
      has_many :course_localizations, inverse_of: :course
      has_many :course_locations, through: :course_localizations
      accepts_nested_attributes_for :course_localizations
    end
    
    class CourseLocation < ActiveRecord::Base
      # attribute city
      has_many :course_localizations
      has_many :courses, through: :course_localizations
    end
    
    class CourseLocalization < ActiveRecord::Base
      belongs_to :course
      belongs_to :course_location
      accepts_nested_attributes_for :course_locations
    end
    

    此时你应该可以

    course = Course.new(
      subject: "Math",
      course_localizations_attributes: [
        { course_location_attributes: { city: "Los Angeles" } },
        { course_location_attributes: { city: "San Francisco" } }]
    )
    
    course.save
    

    【讨论】:

    • 谢谢!我最终在course 新/编辑视图上使用表单构建器测试accepts_nested_attributes_for,并在课程控制器的新操作中添加1.times {@course.courselocations.build}。如果还没有课程位置,我最终要做的是通过 ajax 加载表单。将accepts_nested_attributes_for :course_locations 添加到courselocalizations 模型的目的是什么?
    • 它明确表明您可以将course_location 属性传递给course_localizations 模型,它们将传递给course_locations。您必须将属性传递 2 层深。如果您已经在设置 ​​ajax,我会认真考虑不使用 accepts_nested_attributes_for 而只是发出 2 个单独的 API 请求。祝你好运
    • 谢谢 - 在 ajax 形式中使用 accepts_nested_attributes_for 有什么缺点?另外,我想我不清楚如果这就是您所说的两个单独的 API 请求,我将如何使用您上面提到的两步过程。
    • 实际上,您是否建议课程的创建操作包括 @course.courselocations
    • 我们在这里发表了我的意见,但我不喜欢accepts_nested_attributes_for,因为它需要你一次处理来自多个模型的数据,我发现它更难处理。是的,我指的是 2 个单独的 api 调用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-27
    • 1970-01-01
    • 2011-07-04
    相关资源
    最近更新 更多