Question

I have two objects, Vpn and Organisation

organisation.rb

has_many :vpns, :foreign_key => "managed_by"

vpn.rb

belongs_to :managed_by, :class_name => "Organisation", :foreign_key => "managed_by"

So, the vpns table has a managed_by column which is effectively an organisation id but I don't want to name it organisation_id to avoid confusion.

With this associated, in my list view I can do

<%= vpn.managed_by.nil? ? '' : vpn.managed_by.name %>

To get the name of the organisation the managed_by field relates to but if I try and update the attributes I get ActiveRecord::AssociationTypeMismatch in VpnController#update, so for some reason an object is expected rather than the string, the params sent in the request are as expected:

{"id"=>"1",
 "authenticity_token"=>"RWu39MOqDiu8vbuAfPzyJXAP1CKIaxIFoUjwLl2pemc=",
 "commit"=>"Save",
 "vpn"=>{"id"=>"1",
 "managed_by"=>"999"}}

To avoid leaving anything out, the managed_by in my form is presented as a select menu using collection_select:

<%= collection_select 'vpn', 'managed_by', @organisations, :id, :name, {:selected_value => @vpn.managed_by} %>

Where @organisations is just an active record result containing all organisations.

If I change the belongs_to in vpn.rb to

belongs_to :organisation, :class_name => "Organisation", :foreign_key => "managed_by"

The update works fine but then on the list view I get an error trying to retrieve the name of the organisation:

undefined method `name' for 999:Fixnum
Was it helpful?

Solution

What you're doing is very confusing: you have two things (a belongs-to association and a foreign key) that are both called managed_by. I don't think there is anything you can do to make Rails deal with that. If you want to keep the managed_by column in your database, you should think of another name for your association.

I suggest you use:

belongs_to :organisation, :class_name => "Organisation", :foreign_key => "managed_by" 

like you already tried. To fix the error in your view, you have to use this:

<%= vpn.organisation.nil? ? '' : vpn.organisation.name %>

When using vpn.managed_by Rails looks at the foreign key, which is an integer, not an Organisation object.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top