【问题标题】:Rails 5 - how to dynamically add to the form a nested object using autocompleteRails 5 - 如何使用自动完成将嵌套对象动态添加到表单中
【发布时间】:2018-01-20 04:36:47
【问题描述】:

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

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

我需要这样的东西:

我遇到的问题:

  • Cocoon Gem 仅生成空字段,或者我将在呈现模板时创建。我需要找到一个用户并将他添加到团队中(在不可编辑的字段中)
  • 如果我使用 AJAX,@team = Team.new 仅在 TeamsController 中的新操作中运行,并且当 AJAX 尝试创建 team_user 对象时,Rails 不会记住创建的 @team。要创建team_user 模型的对象需要运行@team.team_users.build(user_id: params[:user_id])user_id 我从自动完成字段中获得,但不知道 @teamteam_id(例如,在 new 操作中 TeamsController)。

【问题讨论】:

标签: ruby-on-rails ajax autocomplete nested-forms has-many-through


【解决方案1】:

1.

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

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

执行此操作的部分在这里:Partial for passenger lookup

它使用茧回调来为每个新乘客运行 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 应用程序。这是相同的路线。我使用 rail263 来开发要在培训应用程序中使用的想法。

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


3.

如果您对这个想法感兴趣,我可以与您一起编辑这篇文章,以包含更完整的答案,并为以后可能阅读此主题的其他人解释它是如何工作的。告诉我。


相关:cocoon issue

【讨论】:

  • 在此示例中,每次添加新字段时,都会为新用户选择输入。该应用程序建议了很多用户,因此使用选择输入来介绍所有用户是不合逻辑的。不幸的是,这不是我所需要的。在我的应用程序中,主窗体中需要一个搜索框,用户可以通过它进行搜索。一旦进入具有自动完成功能的字段,就会找到用户,您必须按 Enter 键或从下拉列表中选择它。然后,该用户应该出现在团队中的用户列表中(没有选择问题的图片)
  • 我想我需要 AJAX,但我不知道如何在 TeamsController 中的 new 操作中保存 @team 以在另一个 AJAX 中构建 team_user @team.team_users.build(user_id: params[:user_id])。跨度>
  • 好的,现在我看到了区别。我希望其他人会回答以帮助您。
【解决方案2】:

我解决了一个非常类似的问题,使用 cocoon 进行嵌套属性和使用 jQuery (Angular UI Typeahead) 的 AngularJS。有几点很重要:

使用 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。

希望这会有所帮助。

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2017-04-19
      • 1970-01-01
      • 1970-01-01
      • 2014-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多