user7383466
user7383466

Reputation:

Ruby on Rails - Seed undefined method error

In my application I have Post & Slide Models. post has many slides & slide belongs_to post.

All of my slides has one image each (I'm using carrierwave gem for uploading), but currently some of my posts doesn't have a image.

Im trying to grab the First slide of each post and upload its image to the post with help of seed.

This is what I have tried in seeds.rb:

posts = Post.all.where(image: nil)

posts.each do |post|
  slide = Slide.where(post_id: post).order('created_at DESC').first
  post.update(remote_image_url: slide.image_url(:thumb_huge))
end

AND

posts = Post.all.where(image: nil)

posts.each do |post|
  slide = Slide.where(post_id: post).order('created_at DESC').first
  post.update(remote_image_url: "http://mywebsite.com/uploads/slide/image/#{slide}/#{slide.image}")
end

When I run this, I get: NoMethodError: undefined method image' for nil:NilClass

Why do I get NoMethodError for image and how can I fix it?

Upvotes: 0

Views: 760

Answers (2)

Divyang Hirpara
Divyang Hirpara

Reputation: 998

You need to just put one condition in your code.

 posts.each do |post|
   if post.slides.count > 0
     slide = Slide.where(post_id: post).order('created_at DESC').first
     post.update(remote_image_url: slide.image_url(:thumb_huge))
   end
 end

I hope it will work for you.

Upvotes: 0

nburkley
nburkley

Reputation: 165

It sounds like you have post that doesn't have any slides, so

Slide.where(post_id: post).order('created_at DESC').first

is returning nil.

Simply checking that slide exists should fix it.

posts.each do |post|
  slide = Slide.where(post_id: post).order('created_at DESC').first

  if slide.present? 
     post.update(remote_image_url: "http://mywebsite.com/uploads/slide/image/#{slide}/#{slide.image}")
  end
end

However, if you have your belongs_to and has_many relations setup correctly, you can simplify this a bit:

posts.each do |post|
  if post.slides.any?
     slide = post.slides.first
     post.update(remote_image_url: "http://mywebsite.com/uploads/slide/image/#{slide}/#{slide.image}")
  end
end

Or you could go even further and only select the posts that have at least one slide in the first place:

posts = Post.joins(:slides).uniq

posts.each do |post|
  slide = post.slides.first
  post.update(remote_image_url: "http://mywebsite.com/uploads/slide/image/#{slide}/#{slide.image}")
end

Upvotes: 1

Related Questions