John Alba
John Alba

Reputation: 315

ruby on rails: suddenly failing method

I am not sure how to present my issue best without posting the whole framework. I have a method duplicate! which should duplicate an object (channel). Usually it works but there is one channel where the method fails and I just don't understand why:

def duplicate!
    channel = Channel.new do |c|
      c.title = title << ' (copy)'
      c.description = description
    end
    channel.nodes += nodes
    playlist.nodes.each { |n| channel.playlist.playlist_items.create(node: n) }
    channel
  end

As said nearly all channels duplicate without a problem, but now I have one channel which fails to get duplicated:

2.3.0 :002 > channel.duplicate!
NoMethodError: undefined method `playlist_items' for nil:NilClass
    from /var/www/app/models/channel.rb:110:in `block in duplicate!'
    from /var/www/app/models/channel.rb:110:in `each'
    from /var/www/app/models/channel.rb:110:in `duplicate!'

Every Channel has Nodes and a Playlist, the error producing Channel has too. I don't really understand the error; how can this method fail depended on the object to duplicate?

Upvotes: 0

Views: 66

Answers (1)

C dot StrifeVII
C dot StrifeVII

Reputation: 1885

The reason this is failing is because one of your channels dont have a playlist record. So this line is failing

playlist.nodes.each { |n| channel.playlist.playlist_items.create(node: n) }

for the channel that does not have a playlist record channel.playlist returns nil so when you do channel.playlist.playlist_items you are calling nil.playlist_items, and since nil does not have the method you get an error.

You could just do this instead of making your on duplicate method fyi

 copy_of_channel5 = channel5.dup

This will duplicate the object

You could also do this

copy_of_channel5 = channel5.clone

Look here for a details explanation of the difference between the 2

Trouble Shooting*

  1. Go to your gem file and add this line gem 'pry'
  2. Run bundle
  3. Replace this line playlist.nodes.each { |n| channel.playlist.playlist_items.create(node: n) } with the below code.

    playlist.nodes.each {|n| binding.pry}

  4. once the execution console pauses type in the console channel.playlist then press enter and post the output.

Upvotes: 1

Related Questions