Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing an association with an alias_attribute

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
like image 936
Carl Edwards Avatar asked Oct 30 '22 19:10

Carl Edwards


1 Answers

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.

like image 128
Alexandre Angelim Avatar answered Nov 15 '22 07:11

Alexandre Angelim