Search code examples
rubyrakeruby-on-rails-5file-type

Find first in array


I'm trying to use the Wikipedia gem to run a rake task and match the first image that is either .jpg, .png or .gif to save to my institute instance. I'm using ruby 2.3 and Rails 5.

My current code is as follows:

namespace :import do
  desc "Import images from Wikipedia"
  task institutes: :environment do
    require 'wikipedia'
    Institute.all.each do |institute|
      school = institute.name
      page = Wikipedia.find(school)
      next if page.content.nil?

      accepted_formats = [".jpg", ".png", ".gif"]
      images = page.image_urls
      image = images.find {|i| i.image_type }

      institute.update!(image_url: image)
    end
    def image_type
      accepted_formats = File.extname(i)
    end
  end
end

This is giving the error NoMethodError: private method 'image_type' called for #<String....>

Is there a more efficient way (and one that works!) of doing this? Sorry, I'm not that experienced in Ruby! I can't work out what the best way to get this to work is; whether to include a method elsewhere or if there's some better way to do it?


Solution

  • I'll recommend you, at first to check is it need to update institute. Next, if you want to use accepted_formats you should define it in constant like: ACCEPTED_IMAGE_FORMATS or send it like argument. Then you should move action that should return accepted image to method, something like first_valid_image(images, accepted_formats). On my opinion, it should looks like:

    namespace :import do
      desc "Import images from Wikipedia"
      task institutes: :environment do
        require 'wikipedia'
        Institute.all.each do |institute|
          school = institute.name
          page = Wikipedia.find(school)
          next if page.content.nil?
    
          accepted_formats = [".jpg", ".png", ".gif"]
          images = page.image_urls
          image = first_valid_image(images, accepted_formats)
    
          institute.update!(image_url: image) if image # this action would run only if image.ni? == false
        end
    
        def first_valid_image(images, accepted_formats)
          images.find do |image|
            File.extname(image).in? accepted_formats
          end
        end
      end
    end