Rails: Model method doesn't execute as a cron task in development

1k views Asked by At

I am currently writing an application in Ruby on Rails that fetches data (videoId as a string, title as a string, thumbnail url as a string, and date of when video was created as a datetime type) from YouTube and saves it to the database.

I have tested YouTube API in pure Ruby before and I know that the output should be correct, specifically it should return all the data I mentioned previously. However, I can't seem to make it work in Rails as a cron job using whenever gem.

Below I have two methods that interact with my model. One of them works and the other one doesn't. The one that doesn't is self.create_youtube_posts and the one that does is the test method I created to check whether it gets executed as a cron job using whenever gem (self.create_test_posts).

Problem for me that I don't even see any error messages with the first one, the code simply doesn't execute. If someone could explain to me why does one method work and the other doesn't, or just simply nudge me in the right direction, your help will be greatly appreciated. Please note that this is not a question asking help on YouTube API, but rather help with my Ruby code.

app/models/post.rb

class Post < ActiveRecord::Base

    # This method is not working!
    def self.create_youtube_posts

        require 'faraday'
        require 'rubygems'
        require 'google/api_client'
        require 'trollop'

        developer_key = "MY_API_KEY_GOES_HERE"
        youtube_api_service_name = "youtube"
        youtube_api_version = "v3"

        opts = Trollop::options do
          opt :maxResults, 'Max results', :type => :int, :default => 18
          opt :order, 'Order', :type => String, :default => 'viewCount' 
          opt :publishedAfter, 'Date', :default => (Time.now - 1.day).to_datetime
        end

        client = Google::APIClient.new(:key => developer_key,
                               :authorization => nil)
        youtube = client.discovered_api(youtube_api_service_name, youtube_api_version)

        # Call the search.list method to retrieve results matching the specified
        # query term.
        opts[:part] = 'id,snippet'
        search_response = client.execute!(:api_method => youtube.search.list,
                                          :parameters => opts)

        search_response.data.items.each do |search_result|
            case search_result.id.kind
                when 'youtube#video'

                    # vi is short for videoId
                    vi = '<iframe width="425" height="349" src="http://www.youtube.com/embed/'
                       + "#{search_result.id.videoId}" 
                       + '" frameborder="0" allowfullscreen></iframe>'

                    # t is short for title
                    t = "#{search_result.snippet.title}"

                    # tn is short for thumbnail
                    tn = "#{search_result.snippet.thumbnails.high.url}"

                    # dt is short for datetime
                    dt = "#{search_result.snippet.publishedAt}"

                    @post = Post.new(videoid: vi, 
                                 title: t, 
                                 thumbnail: tn, 
                                 date: dt)
                    @post.save                  
            end
        end
    end

    # This method is working fine!
    def self.create_test_posts
        @test_post = Post.new(videoid: "Sample video id", 
                              title: "Sample Title", 
                              thumbnail: "Sample Thumbnail", 
                              date: (Time.now).to_datetime)
        @test_post.save
    end
end

For extra reference I included my schedule.rb file that I use to generate cron jobs.

config/schedule.rb

every 1.day do
    runner "Post.create_youtube_posts", :environment => :development
end
2

There are 2 answers

0
Tim On BEST ANSWER

I have managed to solve my problem. And as I expected the problem was with my Ruby code. Below are the changes I made inside post.rb file. I think my variables somehow didn't get passed.

app/models/post.rb --updated

search_response.data.items.each do |search_result|
    case search_result.id.kind
        when 'youtube#video'

            post = Post.new(videoid: "#{search_result.id.videoId}", 
                            title: "#{search_result.snippet.title}", 
                            thumbnail: "#{search_result.snippet.thumbnails.high.url}", 
                            date: "#{search_result.snippet.publishedAt}")
            post.save                   
    end
end
1
chanakya devraj On

Here are the list of commands that may help you debug if your CRON has successfully executed at the given time and period.

grep CRON /var/log/syslog -- check the history of CRON run
bundle exec whenever or whenever -i -- update the crontab
crontab -l -- see the updated cron(for all users)
crontab -e, for a specific user: crontab -e -u username -- list users cron's task
crontab -r -- removes your crontab entry from the cron spooler, but not from crontab file.

Just for the reference:
Minute Hour Day of Month Month Day of Week User Command
(0-59) (0-23) (1-31) (1-12 or Jan-Dec) (0-6 or Sun-Sat)
0 2 * * * root /usr/bin/find