I'm planning on using alias attributes for several of my model associations. Note: I'm completely aware that I can also alias this association via:
belongs_to :type, class_name: "AlbumType"
but would like to further explore the alias_attribute method. With this in mind I have an Album
that belongs to an AlbumType
.
class Album < ApplicationRecord
alias_attribute :type, :album_type
belongs_to :album_type
end
class AlbumType < ApplicationRecord
has_many :albums
end
So far so good. I'd now like to test the aliased association in my album spec. It appears that a traditional belongs_to
shoulda-matcher isn't clever enough to identify that type is an album_type, even after specifying the class name. I'm certainly not adverse to writing a traditional RSpec test but not really sure how in this case. Any help would be much appreciated.
RSpec.describe Album, type: :model do
describe "ActiveRecord associations" do
it { should belong_to(:album_type) }
context "alias attributes" do
it { should belong_to(:type).class_name("AlbumType") }
end
end
end
I wouldn't recommend using alias_attribute
for that purpose. As far as I'm aware, shoulda
uses ActiveRecord::Reflection
to investigate associations. The only thing alias_attribute
does is create methods to proxy messages from the target to the origin through getter, setter and '?' methods. It was clearly intended to work with ActiveRecord attributes and not general purpose methods.
The effect of that is that alias_attribute
won't register those targets as ActiveRecord associations and the current implementation of shoulda
won't be able to catch them.
There are also side effects to that pattern. As you might know, when you create an association, ActiveRecord also creates helper methods to make your life easier. For instance, a belongs_to
also creates:
build_association(attributes = {})
create_association(attributes = {})
create_association!(attributes = {})
By your example, using alias_attribute
won't give you album.build_album_type
and that's something other contributors may be willing to rely upon, as they expect that to be the default behavior.
The best way to handle this is precisely what you told you wouldn't like to do, using the belongs_to
method to create the association under the name you really want.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With