为多态关联选择下拉菜单

主要观点:在使用 Ruby on Rails 构建面向 CRUD 的 Web 应用时,大部分内容较简单,但处理表单中的多态关联是个缺口,可借助全局 ID来解决。以创建包含多态content(可为ArticleVideo)的Post应用为例,通过 Rails CLI 生成相关资源后,发现生成的_form部分表单并非生产就绪,对于多态关联不能使用常规的form.collection_select,而应使用全局 ID。

关键信息

  • 通过bin/rails generate scaffold Post title:string! content:belongs_to{polymorphic}生成相关迁移文件和模型文件。
  • _form部分的form.text_field :content_id方式不可行,因多态关联无单个Content模型。
  • 利用全局 ID 构建单<select>并分组选项的表单字段,如form.select(:content_gid, grouped_options_for_select([['Articles', Article.order(:title).map { |it| [it.title, it.to_gid.to_s] }], ['Videos', Video.order(:title).map { |it| [it.title, it.to_gid.to_s] }]]))
  • 为模型添加content_gidcontent_gid=访问器,前者获取关联content的全局 ID,后者通过全局 ID 设置关联。
  • 可添加初始器config/initializers/polymorphic_belongs_to_gid.rb为带有多态belongs_to关联的所有 ActiveRecord 模型定义*_gid访问器。

重要细节

  • 全局 ID 是应用范围内唯一标识模型实例的 URI,如gid://YourApp/Some::Model/id,可编码类名和 ID 提供多态关联所需信息。
  • 后续更新指出使用签名全局 ID可防止客户端篡改,需修改相关方法和表单代码,如将.to_gid改为.to_sgidGlobalID::Locator.locate改为GlobalID::Locator.locate_signed,并创建Contentable模型关注点用于定义和实现多态content关联所需的接口,如Article模型中的public_namepublic_order方法。
阅读 9
0 条评论