Divjot Mehton
Divjot Mehton

Reputation: 47

testing polymorphic association in rails

I was writing test for updating images in my rails application. The pictures model in my app is a polymorphic association and it belongs to more than one model. I am testing the create, update and destroy action workflow in the integration tests. I have tested the create action successfully. Its working fine. The problem I am having is with the update action.

The model association with the pictures model is given below.

class Picture < ActiveRecord::Base
     belongs_to :pictureable, polymorphic: true

 # each user has one picture
  has_one :picture, as: :pictureable

 #each scoreboard has one picture
  has_one :picture, as: :pictureable, dependent: :destroy

The code for the picture_update_test is given below.

def setup 
    @picture = pictures(:picture_a) #this is the picture associated with pictureable (scoreboard_a)
    @scoreboard = scoreboards(:scoreboard_a) #pictureable is scoreboard_a
  end

  test "successful update where pictureable is scorebaord" do
    patch scoreboard_picture_path(@scoreboard, @picture), picture: {picture: "blank-prof.jpg"}
  end

The code in the picture.yml file is given below.

picture_a:
  picture: "blank-prof.jpg"
  pictureable_type: scoreboard

Once I run the tests, I get the following error.

NoMethodError: undefined method `update_attributes' for nil:NilClass
    app/controllers/pictures_controller.rb:19:in `update'

The picture controller code is also given below.

def update
    @picture = @pictureable.picture
    if @picture.update_attributes(picture_params)
        redirect_to @pictureable
        flash[:success] = "Picture updated successfully"
     else
        redirect_to @pictureable
        flash[:danger] = "An error occured, please try again!"
    end
end

I find out if @pictureable is a user or a scoreboard by splitting the url. The code is given below.

def load_pictureable
    resource, id = request.path.split('/')[1,2]
    @pictureable = resource.singularize.classify.constantize.find(id)
end

I run a before_filter for that method. before_filter :load_pictureable.

In the tests, I don't need to split any url. I am specifically stating the url path, scoreboard_picture_path or 'user_picture_path'. I just have to pass the scoreboard_id and the picture.id. The error states update_attributes for nil class. I am really not sure why I am getting this error. I am not sure if pictures.yml file is correct in terms of the association. As always, any help would be greatly appreciated. Thanks!!

Upvotes: 2

Views: 437

Answers (1)

smathy
smathy

Reputation: 27971

In your yaml you're setting pictureable_type but not picturable_id and so the association is not being built correctly.

You can see the fixtures docs for examples of setting up polymorphic association fixtures, but basically instead of what you're doing you should be able to do something like:

picture_a:
  picture: "blank-prof.jpg"
  pictureable: scoreboard_a (Scoreboard)

That should then allow @pictureable.picture to return the picture.

Upvotes: 2

Related Questions