ActiveAdmin has_many通过编辑1k记录

时间:2017-03-27 12:20:56

标签: ruby-on-rails activeadmin has-many-through

我的模型has_many throughCompany之间建立了Group关系。这是型号代码:

class Company < ActiveRecord::Base
  has_many :company_groups
  has_many :groups, through: :company_groups

  accepts_nested_attributes_for :company_groups, allow_destroy: true
end

class Group < ActiveRecord::Base
  has_many :company_groups
  has_many :companies, through: :company_groups

  accepts_nested_attributes_for :company_groups, allow_destroy: true
end

class CompanyGroup < ActiveRecord::Base
  belongs_to :company
  belongs_to :group

  validates_uniqueness_of :company_id, :scope => :group_id
end

我遇到的问题是,在company_groups表格中有{900} group_id=1

的记录

现在,如果我提供编辑组的选项,它会尝试一次加载所有900条记录。

这是我的/app/admin/group.rb文件:

form do |f|
  return unless current_admin_user.super_admin?
  f.semantic_errors *f.object.errors.keys
  f.inputs 'Group Information' do
    f.input :name
  end
  f.has_many :company_groups do | company_group |
    if !company_group.object.nil?
      company_group.input :_destroy, :as => :boolean, :label => "Destroy?"
    end
    if company_group.object.new_record?
      company_group.input :company, :label => 'Company', :as => :select, :collection => @companies
    else
      company_group.input :company, :input_html => { :readonly => "readonly", :value => company_group.object.company.name }, :as => :string
    end
  end
  f.actions
end

页面花了很多时间加载,所以我启用了检查,如果company_group不是新对象,则在文本框中显示company.name(以只读形式)。但是,这使页面加载时间达到&lt; 25秒,但我仍然认为这不是一次加载这些记录的好方法(因为这可能会挂起浏览器)

我将我的问题分为两部分:

  1. 从优化角度来看,编辑这些记录的最佳方法是什么(搜索/延迟加载等)?如果有人早先做过这件事或类似的功能,你可以共享代码片段来实现

  2. 从ActiveAdmin的角度来看,ActiveAdmin是否提供了批量编辑记录的便捷方式?

  3. 任何帮助都将受到高度赞赏!

    最佳, 普尼特

    编辑:05 / Apr / 17

    这是我正在做的编辑1k记录的事情:

    1. 允许在公司新/编辑页面上添加|编辑组。
    2. 允许通过群组展示/编辑页面上的按钮将公司添加到群组。
    3. 允许编辑|通过群组显示页面从群组中删除公司。
    4. 代码:我公司的型号代码将保持原样
    5. 代码:我的群组型号代码将保持原样
    6. 以下是我的完整代码段:

      class CompanyGroup < ActiveRecord::Base
        validates_uniqueness_of :company_id, :scope => :group_id
      
        belongs_to :company
        belongs_to :group
      
        before_save :ensure_settings
      
      protected
        def ensure_settings
          errors.add(:field_name_2, "You are not allowed to change this field when #{company.boolean_field_name} is set to TRUE") and return false if company.boolean_field_name && field_name_2_changed?
        end
      end
      

      这是我的文件/app/admin/company.rb

      ActiveAdmin.register Company do
        form do |f|
          f.semantic_errors
          f.inputs do
            f.input :field_1
            f.input :boolean_field_name
            f.has_many :company_groups do | company_group |
              company_group.input :group
              company_group.input :field_name_2, as: :radio, collection: [ ['Yes', true], ['No', false] ]
            end
          end
        end
      
        show do
          row :field_1
          row :boolean_field_name
          panel "Groups" do
            table_for company.company_groups do
              column "Group Name" do | company_group |
                company_group.group.name
              end
              column "Field Name 2" do |company_group|
                company_group.group.field_name_2
              end
            end
          end
        end
      end
      

      这是我的文件/app/admin/group.rb

      ActiveAdmin.register Group do
        config.action_items[0] = ActiveAdmin::ActionItem.new :show, only: [:show, :edit] do
          link_to 'Add Company to Group', new_company_group_path(group_id: group.id)
        end
      
        form do |f|
          f.semantic_errors *f.object.errors.keys
          f.inputs do
            f.input :name
            unless f.object.company_groups.any?
              f.has_many :company_groups do | company_group |
                company_group.input :company, as: :select
                company_group.field_name_2, as: :radio, collection: [ ['Yes', true], ['No', false] ]
              end
            end
          end
          f.actions
        end
      
        show do
          attributes_table do
            row :name
          end
      
          panel "Companies" do
            table_for group.company_groups do
              column "" do |company_group|
                link_to("Edit", edit_company_group_path(company_group, group_id: group.id)) + "&nbsp;|&nbsp;".html_safe + (link_to "Delete", company_group_path(company_group), method: :delete, data: { confirm: "Are you sure you want to delete this company from this group?" })
              end
            end
          end
        end
      end
      

      最后我的/app/models/company_group.rb文件:

      ActiveAdmin.register CompanyGroup do
        form do |f|
          f.semantic_errors *f.object.errors.keys
          f.inputs do
            f.input :group
            f.input :company
            f.input :field_name_2, as: :radio, collection: [ ['Yes', true], ['No', false] ]
          end
        end
      
        controller do
          def create
            create! do |format|
              format.html { redirect_to(new_company_group_path(group_id: @company_group.group_id)) }
            end
          end
      
          def update
            update! do |format|
              format.html { redirect_to(group_path(@company_group.group)) }
            end
          end
        end
      end
      

      但现在我遇到了不同的问题:

      1. 我对company_group.rb的自定义模型验证无效。这意味着,每当我尝试创建/更新公司记录并且boolean_field_name设置为TRUE并且field_name_2被更改时,我都没有收到(a)错误消息,(b)虽然field_name_2的更新值未在DB中更新,但我甚至没有在创建/更新操作上停止。它带我回到了展示页面。
      2. 当我尝试更新编辑company_group对象时(通过组显示/编辑页面),情况也是如此。我希望留在company_group的POST / PATCH页面上并显示错误消息,但我正在重定向。这是因为createupdate
      3. 的自定义操作

        编辑:05 / Apr / 17

        我甚至尝试通过以下方式检查valid? company_group条记录:

        def create
          create! do |format|
            if resource.valid?
              format.html { redirect_to(new_company_group_path(group_id: @company_group.group_id)) }
            end
          end
        end
        
        def update
          if resource.valid?
            update! do |format|
              format.html { redirect_to(group_path(@company_group.group)) }
            end
          end
        end
        

        但没有运气!

        在这里&#39;记录日志:

        Started PATCH "/company_groups/877" for ::1 at 2017-04-05 16:51:41 +0530
        Processing by CompanyGroupsController#update as HTML
        Parameters: {"utf8"=>"✓", "authenticity_token"=>"T7jMdOHQygqiX5RSsEkfD1l0h5Q+dpaNrmJlhtiPhpaxen6AyBcv4yD7xAy2GefYpGX0Bvgx4oD7vTMsfIl6fw==", "company_group"=>{"group_id"=>"6", "company_id"=>"623", "field_name_2"=>"true"}, "commit"=>"Update Company group", "id"=>"877"}
        [1m[36mCompanyGroup Load (0.3ms)[0m  [1mSELECT  "company_groups".* FROM "company_groups" WHERE "company_groups"."id" = $1 LIMIT 1[0m  [["id", 877]]
        [1m[35m (0.3ms)[0m  BEGIN
        [1m[36mCompanyGroup Exists (0.5ms)[0m  [1mSELECT  1 AS one FROM "company_groups" WHERE ("company_groups"."company_id" = 623 AND "company_groups"."id" != 877 AND "company_groups"."group_id" = 6) LIMIT 1[0m
        [1m[35mCompany Load (0.3ms)[0m  SELECT  "companies".* FROM "companies" WHERE "companies"."id" = $1  ORDER BY companies.name LIMIT 1  [["id", 623]]
        [1m[36m (0.3ms)[0m  [1mROLLBACK[0m
        [1m[35mCompanyGroup Exists (0.5ms)[0m  SELECT  1 AS one FROM "company_groups" WHERE ("company_groups"."company_id" = 623 AND "company_groups"."id" != 877 AND "company_groups"."group_id" = 6) LIMIT 1
        [1m[36mGroup Load (0.3ms)[0m  [1mSELECT  "groups".* FROM "groups" WHERE "groups"."id" = $1 LIMIT 1[0m  [["id", 6]]
        Redirected to http://localhost:3000/superadmin/groups/6
        Completed 302 Found in 94ms (ActiveRecord: 7.8ms)
        

1 个答案:

答案 0 :(得分:0)

最后,我通过将before_save回调更改为validate来解决问题。 4月/ 4月更新的帖子将继续保持相同,我在/app/models/company_group.rb文件中所做的唯一更改。

class CompanyGroup < ActiveRecord::Base
  validates_uniqueness_of :company_id, :scope => :group_id

  belongs_to :company
  belongs_to :group

  validate :ensure_settings

protected
  def ensure_settings
    errors.add(:field_name_2, "You are not allowed to change this field when #{company.boolean_field_name} is set to TRUE") and return false if company.boolean_field_name && field_name_2_changed?
  end
end

那就是它。感谢我的一位朋友建议我。 :)