I have a Rails 2 app, in development everything works fine but in production one of my views is broken and I'm having a hard time trying to figure out the cause.
The only difference between development and production is that for some reason development uses the mysql2
gem and production uses the original mysql
gem.
First off, if I tail the log, the error I get is:
ActionView::TemplateError (undefined method 'map' for #<Mysql::Result:0xb5ce7844>) on line #15 of app/views/logical_interface/create.rhtml:
Line 15 is
<%= select_tag 'logical_interface[vlan_id]', options_for_select(@vlan_numbers.map(&:reverse)) %>
Which is defined in the Controller as
@pop_id = session[:pop_id]
@vlan_numbers = ActiveRecord::Base.connection.execute("SELECT pop_vlans.id, vlan_number FROM pop_vlans WHERE (pop_id = '" + @pop_id.to_s + "' AND vlan_number = 'Untagged') OR pop_vlans.id NOT IN (SELECT logical_interfaces.vlan_id FROM logical_interfaces) AND pop_id = " + @pop_id.to_s)
I checked the @pop_id
to see if it was failing because it was nil etc but printing it out shows the correct value.
If I remove line 15 and add <%= @vlan_numbers.inspect %>
all I get is #
and if I do debug @vlan_numbers
I get #<Mysql::Result:0xb5db1298>
so I am genuinely stumped.
I had a look to see if there was anything in mysql2
that wasn't in mysql
but all I could find is that mysql2
is just generally better.
Any ideas?
Update
@vlan_numbers = ActiveRecord::Base.connection.select_all("SELECT pop_vlans.id, vlan_number FROM pop_vlans WHERE (pop_id = '" + @pop_id.to_s + "' AND vlan_number = 'Untagged') OR pop_vlans.id NOT IN (SELECT logical_interfaces.vlan_id FROM logical_interfaces) AND pop_id = " + @pop_id.to_s).collect { |r| r['vlan_number'] }
I tried using the above as suggested my mbratch (answer has now been removed) but it's a bit peculiar because the Untagged
option that is added to the list has it's text revered so that it's deggatnU
. I think the same is happening to the select values (which looks like they are just the text instead of the actual id
from the table).
Building on what @Vimsha gave, you could try this which will create an array (list) of [id, vlan_number]
pairs:
@vlan_numbers = ActiveRecord::Base.connection.select_all("SELECT vlan_number, pop_vlans.id FROM pop_vlans WHERE (pop_id = '" + @pop_id.to_s + "' AND vlan_number = 'Untagged') OR pop_vlans.id NOT IN (SELECT logical_interfaces.vlan_id FROM logical_interfaces) AND pop_id = " + @pop_id.to_s).map(&:values)
And get rid of the .map(&:reverse)
on line 15.
If you want to make it truly independent of the order that the SELECT
produces, then slightly longer-hand:
@vlan_numbers = ActiveRecord::Base.connection.select_all("SELECT vlan_number, pop_vlans.id FROM pop_vlans WHERE (pop_id = '" + @pop_id.to_s + "' AND vlan_number = 'Untagged') OR pop_vlans.id NOT IN (SELECT logical_interfaces.vlan_id FROM logical_interfaces) AND pop_id = " + @pop_id.to_s).map { |r| [r["vlan_number"], r["id"]] }