2017-02-16 77 views
0

我们正在从Rails 3.2.13迁移到Rails 4.0.13。grouped_collection_select - group_method从Rails 3更改为4

我们使用Rails帮手grouped_collection_select来嵌套<optgroup> s。

我注意到,从Rails 3.2.13到4.0.2有源变化。

http://apidock.com/rails/v4.0.2/ActionView/Helpers/FormOptionsHelper/grouped_collection_select

我们的方法的使用目前不工作。

这里我们的代码:

<%= f.grouped_collection_select :location_id, @participating_businesses, :"active_locations(#{current_user.id})", :name, :id, :name, {prompt: t('.prompt_select_location')}, class: 'location-selector form-control' %> 

以下是错误:

ActionView::Template::Error (undefined method `active_locations(7)' for #<ParticipatingBusiness:0x005583478f1f90>): 

现在很明显,他们已经改变了如何GET方法的发送。

我在猜测,目前他们正在抓取group_method选项并将其直接放入send(:group_method),这解释了上述错误。

但是,我怎么能传递一个参数给我的group_method依赖于会话(又名current_user)。

查看来源,我不认为这是完全可能的。

http://www.rubydoc.info/docs/rails/4.1.7/ActionView/Helpers/Tags/GroupedCollectionSelect#initialize-instance_method

我应该寻找到重新写这与我们的目标努力,没有助手或一点点更多的手册?

有没有人遇到同样的问题?

+0

鉴于你知道,它不过直接传递'group_method'变量送,如果你试图用'[:active_locations,current_user.id]'呢? –

+0

这是一个非常聪明的解决方法,但是我已经尝试过并且得到了'ActionView :: Template :: Error([:active_locations,7]不是一个符号)''。 – fbelanger

+0

darn:/如果刚刚工作好了,你可能需要为Rails提供功能请求。看起来像普通的'collection_for_select'可以采用'Proc',但是我看到了一个问题,那就是'分组'版本不能以同样的方式工作 –

回答

1

这让人更加沮丧。

我已经钻入Rails 4.0.13的源代码和option_groups_from_collection_for_select的问题函数。

def option_groups_from_collection_for_select(collection, group_method, group_label_method, option_key_method, option_value_method, selected_key = nil) 
    collection.map do |group| 
     option_tags = options_from_collection_for_select(
     group.send(group_method), option_key_method, option_value_method, selected_key) 

     content_tag("optgroup".freeze, option_tags, label: group.send(group_label_method)) 
    end.join.html_safe 
    end 

https://github.com/rails/rails/blob/92703a9ea5d8b96f30e0b706b801c9185ef14f0e/actionview/lib/action_view/helpers/form_options_helper.rb#L455

它直接发送到method_groupsend

正如Taryn East所建议的那样,我已经尝试使group_method成为该方法的一个符号和参数的数组。

但是这提高了TypeError - [:accessible_locations, 15] is not a symbol

这是由send引发的,因为此数组需要在发送调用中使用splat运算符作为方法参数。

现在,这引发了一个重要的问题,我们将如何回答最初的问题。

这是如何工作的?

查看源旧版本的Rails Github上没有表现出任何的区别,所以我用通过代码加强,发现这个:

421: def option_groups_from_collection_for_select(collection, group_method, group_label_method, option_key_method, option_value_method, selected_key = nil) 
422: collection.map do |group| 
423:  group_label_string = eval("group.#{group_label_method}") 
424:  "<optgroup label=\"#{ERB::Util.html_escape(group_label_string)}\">" + 
425:  options_from_collection_for_select(eval("group.#{group_method}"), option_key_method, option_value_method, selected_key) + 
426:  '</optgroup>' 
427: end.join.html_safe 
428: end 

这就是它之前是如何工作的。

由于它是eval-整个group.group_method方法代码,它不会引起undefined method - method_name(args)

所以答案是肯定的,重写是必要的。

我通过使用grouped_options_for_select助手并构建了一个数组来解决此问题。

http://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/grouped_options_for_select

相关问题