委托类型 - Ruby 在 Rails

Delegated types - Ruby on Rails

我仍在尝试为委托类型功能找到一个好的解决方案,但由于我没有找到任何更详细的指南,所以我想在这里问一下。

我感兴趣的是DDH说的:

Delegated types. With this approach, the “superclass” is a concrete class that is represented by its own table, where all the superclass attributes that are shared amongst all the “subclasses” are stored. And then each of the subclasses have their own individual tables for additional attributes that are particular to their implementation.

在他们的示例中,我看到他们在超类上使用了创建者并且是子类的共享属性,他们在评论控制器中使用它,例如:

Entry.create! entryable: Comment.new(content: "Hello!"), creator: Current.user

在这种情况下,creator 将始终相同,因此可以正确实现。

我的问题:

(正如他们提到的)如果您希望超类保留所有其他子类都可以使用的 title 属性(只是一个例子),我该如何处理呢?在这种情况下,标题是可变的(根据用户输入,每个子类的值都会不同),它应该如何在子类控制器上实现。

随机示例:

注意:ofc 我创建了 Productable 模块并包含在子类模型中

# schema.rb

ActiveRecord::Schema.define(version: 2021_08_23_191445) do

  create_table "laptops", force: :cascade do |t|
    t.integer "usb_ports"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "mobiles", force: :cascade do |t|
    t.integer "front_camera"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "Product", force: :cascade do |t|
    t.string "title"
    t.string "description"
    t.string "productable_type"
    t.integer "productable_id"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

end
# laptops_controller.rb

class LaptopsController < ApplicationController

  def new
    @laptop = Laptop.new
  end

  def create
    @laptop = Product.create! productable: Laptop.new(laptop_params) # Here to add what for the title?
    redirect_to @laptop
  end

  private

  def set_laptop
    @laptop = Laptop.find(params[:id])
  end

  def laptop_params
    params.require(:laptop).permit(:usb_ports)
  end
end
# _form.html.erb

<%= form_with(model: @laptop) do |form| %>

  <div class="field">
    <%= form.label :usb_ports %>
    <%= form.number_field :usb_ports %>
  </div>

  <div class="actions">
    <%= form.submit %>
  </div>

<% end %>

我应该像多态关联一样使用嵌套属性吗?有没有人有什么建议?或者,在每个子类和属性上添加 title 属性,而在超类上只添加永不改变的属性?但是,那有什么意义呢?

谢谢:)

and on superclass to add only the attributes that never change

我认为您误读了文档。直到今天我才知道这个功能(所以感谢你引起我的注意),但据我所知,使用这样的超类的目标不是通过 [=17] 保存 space =] 对所有记录都相同的字段(如果它们对所有记录确实相同,则它们不需要是字段。只需对它们进行硬编码或放入配置文件即可)。

因此,如果您要创建评论或消息,每个新评论或消息都会创建自己的条目(本例中的委托超类)。条目不会被共享,因此可以自由地包含可变字段。

是的,由于此功能似乎只是多态关联的一层糖,您 can/should 使用所有相同的方法(嵌套属性等)

万一其他人遇到同样的问题,accepts_nested_attributes_for 选项在我寻找 delegated_type 时不可用,因此我无法对配置的关联对象使用嵌套表单通过 delegated_type.

但是: Rails 7 添加 accepts_nested_attributes_fordelegated_type 的支持 https://github.com/rails/rails/pull/41717