ruby-on-rails 如何在更新活动记录时更新has_and_belongs_to_many表

ac1kyiln  于 2023-02-17  发布在  Ruby
关注(0)|答案(1)|浏览(166)

我在执行has_and_belongs_to_many时遇到问题,我的数据结构如下

# app/models/student.rb
class Student < ApplicationRecord
  belongs_to :city
  belongs_to :degree
  has_and_belongs_to_many :services, optional: true  
end
# app/models/service.rb
class Service < ApplicationRecord
  has_and_belongs_to_many :student, optional: true
  belongs_to :vendor
  belongs_to :degree, optional: true
end

在我的数据库模式中,我有这个表以及student和service表。

create_table "services_students", id: false, force: :cascade do |t|
    t.integer "service_id", null: false
    t.integer "student_id", null: false
  end

如果学生要与服务关联,我需要在services_controller. create()中添加一些行

# POST /services or /services.json
  def create
   
    @service = Service.new(service_params)

    for student in params[:service][:student]
      if student != ""
        @service.student << Student.find(student)
      end
    end

    respond_to do |format|
      if @service.save
        format.html { redirect_to service_url(@service), notice: "Service was successfully created." }
        format.json { render :show, status: :created, location: @service }
      else
        format.html { render :new, status: :unprocessable_entity }
        format.json { render json: @service.errors, status: :unprocessable_entity }
      end
    end
  end

这样表格就正确地保存了信息。但是,在update()函数中,当保存记录时,service_students表格记录被复制而不是被更新。
在services_controller中,我将许可参数设置为:

# service_controller.rb
    # Only allow a list of trusted parameters through.
    def service_params
      params.require(:service).permit(:student, :vendor_id, :degree_id, :category, :description)
    end

我的形式是这样的

# .... begin of form ... 
      <%= form.label :student, "Aluno(s)" %>
      <%= form.collection_check_boxes :student, Student.all, :id, :name do |b| 
        b.label(class:"w-full ") { b.check_box(class:"rounded", checked: @service.student.ids.include?(b.object.id)) + b.text  }

# .... more fields of form ....

我不明白我做错了什么。update函数,甚至create(),不应该在不添加更多代码的情况下处理这个问题吗?
我试着学习了互联网上的一些教程,我意识到activeRecord应该生成students_ids或students属性来正确注册关联,但我不明白为什么会发生这种情况,或者为什么在我的模型中它被称为student。(可能有什么地方出错了)

>> rails console
service = Service.find(1) # get the Service with id: 1
student1 = Student.find(1) # get the Student with id: 1
student2 = Student.find(2) # get the Student with id: 2

service.students << student1 # error
service.student << student1 # works 

service.students #error #method missing
service.student # display all students relationship

这是应该发生的吗?

busg9geu

busg9geu1#

关联应具有复数名称:

class Service < ApplicationRecord
  has_and_belongs_to_many :students # this should be plural! 
  belongs_to :vendor
  belongs_to :degree, optional: true
end

has_and_belongs_to_many :students生成的students_ids方法与您的输入一起使用:

<%= form.collection_check_boxes :student_ids, Student.all, :id, :name do |b| %>
 <%= b.label(class:"w-full") { b.check_box(class:"rounded") + b.text  } %>
<% end %>

您需要将一组ID加入白名单:

def service_params
  params.require(:service)
        .permit(
                :vendor_id, :degree_id, 
                :category, :description,
                student_ids: [] # permits an array of values 
             )
end

把这些废物处理掉:

def create
    @service = Service.new(service_params)
    respond_to do |format|
      if @service.save
        format.html { redirect_to @service, notice: "Service was successfully created." }
        format.json { render :show, status: :created, location: @service }
      else
        format.html { render :new, status: :unprocessable_entity }
        format.json { render json: @service.errors, status: :unprocessable_entity }
      end
    end
  end

students_ids=方法也是由has_and_belongs_to_many :students创建的,它将自动添加/删除连接表中的行。

相关问题