活动管理员嵌套 select

Active Admin nested select

我在 rails 项目上的 ruby 有 Active Admin gem。我想做的是创建一个产品并有 2 个 select 框(1-类别,2-部门),其中第二个根据第一个更改其内容。经过无数小时的搜索,我仍然无法正常工作。

class Product < ActiveRecord::Base
belongs_to :category, dependent: :destroy, counter_cache: true
has_one :department, through: :category
end

class Category < ActiveRecord::Base
belongs_to :department, counter_cache: true
has_many :products
end

class Department < ActiveRecord::Base
end

我想这样做的原因是因为某些部门可能具有相同的类别名称,这会造成混淆并且会将产品添加到错误的部门。

我试过 question 9579402 但我对他的问题的理解是他只有 2 个模型并且他正在从 selected 类别

创建子类别

这是一个熟悉的东西,但他使用了一个get ajax请求Git/Dglgmut/6328501

尝试 question 9579402 得到错误:

Started POST "/admin/products/change_categories" for ::1 at 2016-03-30 14:51:09 +0300
ActionController::RoutingError (No route matches [POST]    "/admin/products/change_categories"):

这是我在 routes.rb

routes.rb = post 'change_categories'        =>'products#change_categories'  
http://localhost:3000/rails/info/routes = change_categories_path    POST    /change_categories(.:format)    products#change_categories 

我想这是因为我可以使用 Member Actions for Active admin,所以我试了一下

member_action :change_categories, :method => :get do
  @categories = Department.find_by_id(params[:department_id]).try(:categories)
  render :text=>view_context.options_from_collection_for_select(@categories, :id, :category_number)
end

但是还是出现了和之前一样的错误。如有任何帮助,我们将不胜感激。

更新: 我是这方面的初学者,但如果我是正确的,change_categories 应该在类别控制器中,因为它正在产品控制器中搜索该方法,

POST "/admin/products/change_categories"

所以我将类别资源添加到 Active Admin 并将该方法添加到类别控制器,但是现在有办法使用该控制器吗?类似于:

f.input :department, :input_html => { :onchange => remote_request(controller => "categories", :post, :change_categories, {:department_id=>"$('#department_id').val()"}, :category_id) }

问题是您的 member_action 方法是 "get" 并且您正在向控制器发帖。从 "POST" 更改为执行 Get 请求应该可以解决问题。

所以在无数个小时之后,我设法让它工作了。我认为问题出在旧版本或我获取代码的模型之间的差异。因此,在 Active Admin 而不是 member_action 中,我使用了 collection_action 这在路由中更有意义,因为 member_action 创建路由 /admin/products/:id/change_categories(.:format) 干扰显示动作并使用它代替 change_categories 动作。

所以这里 collection_action:

collection_action :change_categories, :method => :get do
@categories = Category.where("department_id = ?", Department.find(params[:product_department_id]))
render :text => view_context.options_from_collection_for_select(@categories, :id, :name)
end

这会生成正确的路由 admin/products/change_categories,我现在可以在其中传递参数 [:product_departmemnt_id],它是 select 来自 select 框的 ID。

这是它从中获取 ID 的地方:

f.input :description
    f.input :department, prompt: "Select department", :input_html => {
    onchange: remote_get("change_categories", 'product_department_id', :product_category_id)
}
    f.input :category

给一些 ajax 初学者的提示,一定要检查网页的源代码,看看你是否使用了正确的 id 或 class 或其他什么,这让我很头疼。

接下来要添加的是辅助方法,有两种方法可以做到这一点,在 application_helper.rb 或 app/helpers 中。如果你将它添加到 appication_helper.rb 你必须将它包含到 config/initializers/active_admin.rb initializer:

ActiveAdmin.setup do |config|
  ....
  some config
  ....
end

module ActiveAdmin::ViewHelpers
  include ApplicationHelper
end

但是它可以访问它的所有辅助方法,我认为这些方法是不需要的,或者 might/might 不会减慢它的速度,所以我在 app/helpers 中创建了一个名为 [=31] 的新文件夹=] 并创建了一个文件 "form_helper.rb" 这段代码来自 Dglgmut/6328501 git

def remote_get(path, member,target_tag_id)
 "$.get('#{path}/?#{member}=' + $('##{member}').val(),
  function(data) {$('##{target_tag_id}').html(data);}
 );"
end

对 js 了解不多,但我假设这会向 admin/products/change_categories/?product_department_id=1 发出 get 请求,其余的发生在辅助方法中。如果有人偶然发现了这一点,我希望这对您有所帮助并提供您需要的信息。我还建议您进行所谓的 "rubber duck" 调试,不开玩笑,这有时会有所帮助。