Rails 5 - 如何使用自动完成功能向表单动态添加嵌套对象

Rails 5 - how to dynamically add to the form a nested object using autocomplete

我有 3 个模型 - 团队、用户和 team_user(has_namy:通过)。以编辑和新团队的形式,可以使用自动完成输入动态添加该团队的成员。

app/models/user.rb

class User < ApplicationRecord
  has_many :team_users
  has_many :teams, through: :team_users
  accepts_nested_attributes_for :team_users, :teams, allow_destroy: true
end

app/models/team.rb

class Team < ApplicationRecord
  has_many :team_users
  has_many :users, through: :team_users
  accepts_nested_attributes_for :team_users, allow_destroy: true, reject_if: proc { |a| a['user_id'].blank? }
end

app/models/team_user.rb

class TeamUser < ApplicationRecord
  belongs_to :team
  belongs_to :user
  accepts_nested_attributes_for :team, :user, allow_destroy: true
end

我需要这样的东西:

我遇到的问题:

1.

在此示例应用程序中,rail263 example application,我使用 cocoon、simpleform 和 select2 创建一个可搜索的下拉框来搜索姓名列表以将乘客添加到租赁记录。

我相信这就是您想要的用例。

这样做的部分在这里:Partial for passenger lookup

它使用 cocoon 回调来为每位新乘客进行 select2 查找 运行。

rental record model中,关联是:

 belongs_to :customer
 belongs_to :vehicle

  # delete associated records..  
 has_many :passengers, dependent: :destroy
 has_many :pasenger_lists, :through => :passengers, :class_name =>    'PasengerList'

 accepts_nested_attributes_for :pasenger_lists
 accepts_nested_attributes_for :passengers,  allow_destroy: true

激活 select2 下拉菜单的回调在这里:callback

  $('#passengers')
    .on('cocoon:after-insert', function() {
      $(".dgselect2").select2({
    });

在您的代码中,您是否将强参数中需要的项目列入白名单?看这里:controller

params.require(:rental_record).permit(
  :customer_id, :vehicle_id, :start_date, :end_date, :lastUpdated,
  passengers_attributes: [:id, :description, :name, :output,     :pasenger_list_id, :_destroy , pasenger_lists_attributes: [:id, :clocknum, :name, :active, :_destroy]]
  )        

2.

我在这个应用程序中也做了同样的想法:training app

只是rail263 app不同型号而已。这是沿着同样的路线。我使用 rail263 来开发要在培训应用程序中使用的想法。

您可以在此处试用培训应用程序:demo
- 使用用户 = reg 和密码 = a2a2
登录 - 单击 add tr_training_employee 按钮查看它是否正常工作。


3.

如果您对这个想法感兴趣,我可以与您一起编辑此 post 以包含更完整的答案,并向以后可能阅读此主题的其他人解释它的工作原理。让我知道。


相关:cocoon issue

我解决了一个非常相似的问题,使用 cocoon 嵌套属性和 AngularJS 与 jQuery (Angular UI Typeahead)。有一些要点:

使用Angular/jQuery更新data-association-insertion-template更新相关data()每次选择的东西。由于浏览器对数据元素的缓存特性,此属性的更改不会自动反映出来。所以我绑定了按钮的 click 事件:

$(this).data('association-insertion-template', $(this).attr('data-association-insertion-template'));

相应地为 cocoon 编写嵌套字段模板,以便您可以用选定的值填充它。当我使用 Angular 时,我的就像 (Slim 模板语法):

tr.nested-fields
  td
    = f.object.persisted? ? f.object.full_name : '{{angularModel.full_name}}'

该前端原型几乎可以正常工作,但在每个父对象更新时,所有现有的嵌套字段都会翻倍。所以我覆盖了父模型中的嵌套属性方法(参见 this thread):

def items_attributes=(attributes)
  self.items = attributes.values.map { |item| Item.find(item['id']) }
  super(attributes)
end

最后一个问题是我可以多次添加嵌套记录。为了限制这种行为,我只是在 typeahead AJAX 查询中删除所有已经使用的 ID。

希望这对您有所帮助。

如果你有类似的项目,你可以用这个解决这个问题gemdynamic_nested_forms