简体   繁体   English

在没有accepts_nested_attributes_for的情况下,如何在Rails中更新嵌套属性?

[英]How do I update Nested Attributes in Rails without accepts_nested_attributes_for?

I'm working on a project for a class where I have a very large form with Nested Models. 我正在为一个班级的项目工作,其中的嵌套模型具有很大的形式。 Here are the models that are important to the form, as well as their associations: 以下是对表单及其关联很重要的模型:

  • Course: has_many :time_blocks, has_many :tags, through: :taggings, belongs_to :institution, has_many :roles, has_many :users, through: :roles 课程:has_many:time_blocks,has_many:tags,通过::taggings,belongs_to:institution,has_many:roles,has_many:users,通过::roles

  • TimeBlock: belongs_to :course TimeBlock:belongs_to:课程

  • Tag: has_many :taggings 标签:has_many:taggings
  • Tagging: belongs_to :tag, belongs_to :taggable_type 标记:belongs_to:tag,belongs_to:taggable_type
  • Institution: has_many :courses, has_many :users 机构:has_many:courses,has_many:users
  • Role: belongs_to :course, belongs_to :user 角色:belongs_to:课程,belongs_to:用户

I am able to create the Nested Form correctly, but I can't get the Nested Models to update correctly. 我能够正确创建嵌套表单,但是无法正确更新嵌套模型。 Here is the controller, the form is very long, but I have provided the params for the Nested Models. 这是控制器,形式很长,但是我提供了嵌套模型的参数。 Note, I cleared out the values from the params, but some of the params have ID values because they exist in the db. 注意,我从参数中清除了值,但是某些参数具有ID值,因为它们存在于db中。 I've also included the CoursesHelper to show the helper methods I'm using in the controller. 我还包括了CoursesHelper,以显示我在控制器中使用的帮助器方法。

app/controllers/courses_controller.rb app / controllers / courses_controller.rb

  def new
    @course = current_user.courses.new

    @course.institution = Institution.new

    4.times { @course.tags.build }
    7.times { @course.time_blocks.build }
  end

  def create
    @course = Course.new(params[:course])

    @course.institution = Institution.new(params[:institution])

    filled_tags = set_tags(params[:tag])
    @course.tags.build(filled_tags)

    filled_time_blocks = set_time_blocks(params[:time_block])
    @course.time_blocks.build(filled_time_blocks)

    if @course.save
      Role.create!(
        user_id: current_user.id, 
        course_id: @course.id, 
        title: 'instructor'
      )

      redirect_to @course
    else
      (4 - filled_tags.count).times { @course.tags.build }
      (7 - filled_time_blocks.count).times { @course.time_blocks.build }

      flash.now[:errors] = @course.errors.full_messages
      render :new
    end
  end

  def edit
  end

  def update
    filled_time_blocks = set_time_blocks(params[:time_block])
    filled_time_blocks.each do |time_block| 
      @course.time_blocks.update_attributes(time_block)
    end 

    filled_tags = set_tags(params[:tag])
    filled_tags.each { |tag| @course.tags.update_attributes(tag) }
    # @course.tags.update_attributes(filled_tags)

    # @course.time_blocks.update_attributes(filled_time_blocks)
    fail
    if @course.update_attributes(params[:course])
      redirect_to @course
    else
      flash.now[:errors] = @course.errors.full_messages
      render :edit
    end
  end

app/helpers/courses_helper.rb app / helpers / courses_helper.rb

  def set_time_blocks(entries)
    result = []

    days = entries[:day_of_week].reject! { |day| day.blank? }

    days.each do |day|
      time_block = {}

      time_block[:day_of_week] = day
      time_block[:start_time] = entries[day][:start_time]
      time_block[:end_time] = entries[day][:end_time]
      time_block[:id] = entries[day][:id]

      result << time_block
    end

    result
  end

  def set_tags(entries)
    [].tap do |tags|
      entries.each do |entry|
        tags << entry unless entry.values.all?(&:blank?)
      end
    end
  end

  def find_course
    if params.include?(:id)
      @course = Course.find(params[:id])
    else
      flash[:notice] = "Sorry, Could Not Find Course."
      redirect_to current_user
    end
  end

TimeBlock Params 时间块参数

{"sun"=>{"start_time"=>"", "end_time"=>"", "id"=>""}, "mon"=>{"start_time"=>"", "end_time"=>"", "id"=>"3"}, "tue"=>{"start_time"=>"", "end_time"=>"", "id"=>"4"}, "wed"=>{"start_time"=>"", "end_time"=>"", "id"=>"5"}, "thu"=>{"start_time"=>"", "end_time"=>"", "id"=>"6"}, "fri"=>{"start_time"=>"", "end_time"=>"", "id"=>"7"}, "sat"=>{"start_time"=>"", "end_time"=>"", "id"=>""}, "day_of_week"=>[]}

Tag Params 标签参数

[{"name"=>"", "id"=>"4"}, {"name"=>"", "id"=>""}, {"name"=>"", "id"=>""}, {"name"=>"", "id"=>""}]

If you cant make it work with accepts_nested_attributes_for then you'll have to write your own setter method(s) manually. 如果您无法使其与accepts_nested_attributes_for则必须手动编写自己的setter方法。 Something like: 就像是:

class Course < ActiveRecord::Base
  def tag_attributes=(tags)
    tags.each do |tag|
      self.tags.build(tag)
    end
  end
end

The method name (tag_attributes= in my example) needs to match the key name that the tag params are listed under 方法名称(在我的示例中为tag_attributes =)需要与标签参数在下面列出的键名匹配

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM