2017-02-16 34 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