2017-02-16 33 views
0

В моей заявке есть Post & Slide Модели. post has many slides & slide belongs_to post.Рубины на рельсах - ошибка с неопределенным методом семян

Все из моих слайдов имеет одно изображение каждый (я использую carrierwave gem для загрузки), но в настоящее время некоторые из моих постов не имеет изображения.

Im пытается захватить Первый слайд каждого сообщения и загрузить его изображение в сообщение с помощью seed.

Это то, что я пытался в 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 

И

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 

Когда я запускаю это, я получаю: NoMethodError: undefined method image' for nil:NilClass

Почему я получаю NoMethodError для image и как я могу это исправить?

+0

Вам нужно показать код, но я предполагаю, что сообщение не имеет изображения, вам нужно сначала создать соответствующий экземпляр модели. – lcguida

+0

изменить 'posts = Post.all.where (image: nil)' to 'posts = Post.where (image: nil)' –

ответ

0

Похоже, у вас есть post, что не имеет никаких слайдов, так

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

возвращается nil.

Просто проверьте, что slide существует, исправить.

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 

Однако, если у вас есть настройки belongs_to и has_many отношения правильно, вы можете упростить этот бит:

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 

Или вы могли бы пойти еще дальше и выбрать только те сообщения, которые имеют, по меньшей мере, один предмет слайдов:

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 
+0

Спасибо @nburkley. Когда я запускаю любое из решений, он запускает 'select', а не' update'. ** Это в моем терминале: ** Slide Load (0.3ms) SELECT «слайды». * FROM «слайды» WHERE «слайды». «Post_id» = 7257 ORDER BY created_at DESC LIMIT 1 01 (0.1ms) BEGIN 01 (0.1ms) ROLLBACK' –

+0

Похоже, когда я * выбираю * 'слайд', он запускает только« Slide Load », а не« post update ». Я протестировал, удалив 'slide = post.slides.first' из' posts.each do', затем было опубликовано обновление для публикации.Но как я могу выбрать «слайд», если у меня есть его «post.each do» –

+0

Если вы видите «ROLLBACK» в журналах, это происходит из-за сбоя 'update'. Вероятно, существует некоторая логика проверки, которая препятствует сохранению модели. Попробуйте добавить некоторые протоколирования или точки останова, чтобы найти, почему он не будет сохранять - вот как можно добавить точку 'binding.pry, если post.update (.. ваши изменения здесь ..)' – nburkley

0

Вам нужно просто поставить одно условие в свой код.

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 

Я надеюсь, что это сработает для вас.

+0

Спасибо @Divyang. Когда я запускаю ваше решение, он запускает 'select', а не' update'. ** Это в моем терминале: ** Slide Load (0.3ms) SELECT «слайды». * FROM «слайды» WHERE «слайды». «Post_id» = 7257 ORDER BY created_at DESC LIMIT 1 01 (0.1ms) BEGIN 01 (0.1ms) ROLLBACK –

+0

вы можете добавить полный журнал запроса? –

+0

Как упоминалось, его просто ** Слайд-нагрузка (0,3 мс) SELECT «слайды». * FROM «слайды» ГДЕ «слайды». «Post_id» = 7257 ORDER BY created_at DESC LIMIT 1 01 (0.1ms) BEGIN 01 (0.1ms)) ROLLBACK ** и изменяется только предмет: post_id –