【问题标题】:How do I update Nested Attributes in Rails without accepts_nested_attributes_for?在没有accept_nested_attributes_for 的情况下,如何在Rails 中更新嵌套属性?
【发布时间】:2013-12-13 01:32:29
【问题描述】:

我正在为一个班级开展一个项目,其中我有一个带有嵌套模型的非常大的表格。以下是对表单很重要的模型及其关联:

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

  • 时间块:belongs_to :course

  • 标签:has_many :taggings
  • 标记:belongs_to :tag,belongs_to :taggable_type
  • 机构:has_many :courses,has_many :users
  • 角色:belongs_to :course,belongs_to :user

我能够正确创建嵌套表单,但无法正确更新嵌套模型。这是控制器,表格很长,但我提供了嵌套模型的参数。请注意,我从参数中清除了值,但某些参数具有 ID 值,因为它们存在于数据库中。我还包含 CoursesHelper 以显示我在控制器中使用的辅助方法。

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

  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

时间块参数

{"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"=>[]}

标签参数

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

【问题讨论】:

  • 你为什么不想使用accepts_nested_attributes_for
  • 不应该鼓励这种方法和问题,因为这不是 rails 的设计方式。除非您有充分的理由不使用 accepts_nested_attributes_for,否则您不应该编写任何手动代码。

标签: ruby-on-rails nested-forms nested-attributes


【解决方案1】:

如果你不能让它与accepts_nested_attributes_for 一起工作,那么你将不得不手动编写你自己的setter 方法。比如:

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

方法名称(在我的示例中为 tag_attributes=)需要与标签参数下列出的键名称匹配

【讨论】:

    猜你喜欢
    • 2011-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多