简体   繁体   English

委托类型 - Ruby on Rails

[英]Delegated types - Ruby on Rails

I am still trying to find a good solution to the Delegated Type feature and as I didn't find any good more detailed guide, I would like to ask here.我仍在尝试为委托类型功能找到一个好的解决方案,因为我没有找到任何更好的更详细的指南,我想在这里问一下。

What I am interested in is what DDH said:我感兴趣的是 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.

In their example, I saw that they use the creator on superclass and is a shared attribute for the subclasses, and they are using that in the comments controller like:在他们的示例中,我看到他们在超类上使用了创建者,并且是子类的共享属性,他们在评论控制器中使用了它,例如:

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

In this case, the creator will be always the same, so correctly is implemented like that.在这种情况下, creator将始终相同,因此正确实现。

My question :我的问题

(As they mention) what if you want the superclass to keep the title attribute (just an example), which all the other subclasses can use, how can I handle that? (正如他们所提到的)如果您希望超类保留所有其他子类都可以使用的 title 属性(只是一个示例)怎么办,我该如何处理? In this case, the title is mutable (value will be different on each subclass based on user input), how it should be implemented on the subclass controller.在这种情况下,标题是可变的(根据用户输入,每个子类的值都会不同),它应该如何在子类控制器上实现。

random example:随机示例:

Note: ofc I created the Productable module and included in the subclass models注意: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 %>

Should I use nested attributes as with polymorphic associations?我应该像多态关联一样使用嵌套属性吗? Does anyone have any suggestions?有没有人有什么建议? Or maybe, to add the title attribute on each subclass and the attributes, and on superclass to add only the attributes that never change?或者,在每个子类和属性上添加标题属性,在超类上仅添加永不改变的属性? But then, what's the point?但是,这又有什么意义呢?

Thank you :)谢谢 :)

and on superclass to add only the attributes that never change并在超类上只添加永远不会改变的属性

I think you are misreading the docs.我认为您误读了文档。 I didn't know about this feature until today (so thank you for drawing my attention to it), but from what I can see, the goal of using a superclass like this is not to save space by reusing/sharing fields that are the same for all records (if they are truly the same for all records, they don't need to be fields. Just hardcode them or put into a config file).直到今天我才知道这个特性(所以感谢你引起我的注意),但从我所见,使用这样的超类的目标不是通过重用/共享字段来节省空间所有记录都相同(如果它们对于所有记录确实相同,则它们不需要是字段。只需对它们进行硬编码或放入配置文件中)。

So if you're creating Comments or Messages, each new comment or message will create its own Entry (the delegated superclass in this example).因此,如果您正在创建评论或消息,则每个新评论或消息都将创建自己的条目(本示例中的委托超类)。 An Entry won't be shared and is therefore free to have mutable fields.条目不会被共享,因此可以自由地拥有可变字段。

And yes, since this feature seems to be just a layer of sugar over polymorphic associations, you can/should use all the same methods (nested attributes, etc.)是的,由于此功能似乎只是多态关联上的一层糖,您可以/应该使用所有相同的方法(嵌套属性等)

In case someone else faces the same issue, the accepts_nested_attributes_for option wasn't available for delegated_type when I was looking for that, hence I couldn't use nested forms for associated objects configured via delegated_type .如果其他人面临同样的问题,当我寻找它时, accepts_nested_attributes_for选项对delegated_type不可用,因此我无法对通过delegated_type配置的关联对象使用嵌套表单。

BUT: Rails 7 adds accepts_nested_attributes_for support to delegated_type https://github.com/rails/rails/pull/41717 🎉但是: Rails 7添加了accepts_nested_attributes_for支持到delegated_type https://github.com/rails/rails/pull/41717 🎉

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

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