I created the migration according the polymorphic rails cookbook. The models have the following relations
class TeachingAssistant < ActiveRecord::Base
belongs_to :ta_type, polymorphic: true
end
class University < ActiveRecord::Base
has_many :teaching_assistants, as: :ta_type
end
In the rails console i am able to do the following
t = TeachingAssistant.create name: 'name'
u = University.create name: 'hogwarth'
t.update ta_type: u
University.last.teaching_assistants.last
But why is it not possible to use the as: :ta_type association name directly;
University.last.ta_type
results for example in undefined method for ta_type. But typing
University.last.ta_type
and tab-completing returns the following list
University.last.ta_type
University.last.ta_type=
University.last.ta_type_id
University.last.ta_type_id=
University.last.ta_type_id?
University.last.ta_type_id_before_type_cast
University.last.ta_type_id_came_from_user?
University.last.ta_type_id_change
University.last.ta_type_id_changed?
University.last.ta_type_id_was
....
Why is this not possible? Is it by design or am i doing something wrong?
Related
Please have a look at this basic associations setup (Rails 4.2.1):
class Parent < ActiveRecord::Base
has_many :kids
end
class Kid < ActiveRecord::Base
belongs_to :school
end
class School < ActiveRecord::Base
end
With these models the next code works as expected and keeps the association loaded:
parent = Parent.first
parent.kids.to_a
parent.association(:kids).loaded? # => true
But: adding an .includes(:school) prevents the association being loaded/cached for some reason
parent = Parent.first
parent.kids.includes(:school).to_a
parent.association(:kids).loaded? # => false
Looking at SQL logs I see exact the same select query so I expect the association to be loaded/cached.
The question
Why is this happening?
ActiveRecord preloads/caches parent.kids in the first example. I want to understand why its not possible in the second example with includes call?
An ideal answer for me would include references to the sources.
Thanks for any help
P.S.
The workaround I'm using is setting association.target manually:
parent.association(:kids).target = parent.kids.includes(:school).to_a
I currently a polymorphic association set up like this
class Reading < ApplicationRecord
has_one :audio, as: :audioable
accepts_nested_attributes_for :audio
end
class Audio < ApplicationRecord
belongs_to :audioable, polymorphic: true
end
In my RSPEC test, I have this set up
#reading = attributes_for(:reading, creator: #user, body: "who let the dogs out? Must be me\n\nMeMeMe")
#reading[:audio_attributes] = attributes_for(:audio)
However, I get the following errors when posting this #reading to the reading#create controller
{:errors=>{:"audio.audioable"=>["must exist"]}}
For non-polymorphic associations I've gotten it to create both the parent and nested resources using inverse_of but I'm not sure how to do it for polymorphic associations.
inverse_of can't be used for polymorphic associations, have you looked at Single Table Inheritance it could be a good solution depending of what you are trying to achieve
Hey guys I broke a bit of rails convention by using underscores instead of camelcasing on a class name (Ui_1_Log instead of Ui1Log) and now when I refer to the association it isnt finding the right class. For example:
class Ui_1_Log < ActiveRecord::Base
belongs_to :account
end
class Account < ActiveRecord::Base
has_many :ui_1_logs
end
Now when I call the association in the rails console it doesnt work because it returns a classname as Camelcase when it needs to keep the underscores...
x = Account.first
x.ui_1_logs.first #returns nameError: uninitialized constant Account::Ui1Log
It needs to be Account::Ui_1_Log but I don't know how to force that...Any ideas?!
You can set the class name on the association with class_name option.
class Account < ActiveRecord::Base
has_many :ui_1_logs, class_name: 'Ui_1_Log'
end
But I still recommend to follow conventions.
I have the following models
class Business < ActiveRecord::Base
has_one :name_object, as: :nameable
end
class NameObject < ActiveRecord::Base
has_one :user
belongs_to :nameable, polymorphic: true
end
However, when I try to build a business with a name and user, like so:
business = Business.new
business.build_name_object
business.name_object.build_user
Rails throws the error ActiveRecord::UnknownAttributeError in BusinessesController#new unknown attribute: name_object_id.
I've created the database with nameable_id and nameable_type columns for the name_objects table, but I don't think I need a name_object_id foreign key on the business table as well. What am I missing?
Seems like since your NameObject has_one :user, that the User would be the one that belongs_to :name_object, therefore Rails is looking for name_object_id to be a field in the user table and its throwing that error. Just a hunch so, maybe, post your User model code.
I have some issues with the polymorphic associations in Rails 3. My model looks like this:
class Address < ActiveRecord::Base
belongs_to :contactable, :polymorphic => true
end
class OrganisationUnit < ActiveRecord::Base
# some other associations
end
# Subclass of OrganisationUnit
class Company < OrganisationUnit
has_one :address, :as => :contactable
end
Now, when I want to get the Address of a Company, Rails generates the following SQL-Query:
SELECT `addresses`.* FROM `addresses` WHERE (`addresses`.contactable_id = 1021 AND `addresses`.contactable_type = 'OrganisationUnit') LIMIT 1
In my opinion it's wrong, because the contactable_type should be "Company".
Is there any way I can fix this or tell rails that OrganisationUnit is just an abstract base class?
The is an expected behavior. When you link a STI table to a polymorphic association, Rails stores the base class name rather than the inherited class names. The STI type conversion happens after the object lookup by id.