How can I refresh the cache of model manually in rake file - ruby-on-rails

How can I refresh the cache of model manually
I can cached pages with fragment,
and refresh it in outside rake task
But I have no idea how to refresh the cache inside the controller for fetching data from DB.
How could I refresh the cache in Rake file
def get_max_and_min_routes(airline_name, from, to)
Rails.cache.fetch("I_AM_CACHE_KEY") do
FETCH_FROM_DB
end
end
rake file
action_controller = ActionController::Base.new
action_controller.expire_fragment("body_header")
action_controller.expire_fragment("index")
action_controller.expire_fragment("welcome_index_controller")
action_controller.expire_fragment("footer")
index.haml
- cache("index", skip_digest: true) do
= render "historical_prices"
= render "common/recently_changed_prices"

You can access the cache directly through the Rails.cache command like so:
> Rails.cache.read('body_header')
=> '<p>fragment cache entry</p>'
> Rails.cache.delete('body_header')
=> true
> Rails.cache.read('body_header')
=> nil
So for your example:
def get_max_and_min_routes(airline_name, from, to)
content_to_be_cached = FETCH_FROM_DB
Rails.cache.write('body_header', content_to_be_cached)
end
This should work in your rake file and also from the console.

Related

Rails session still alive after db:drop

I'm curious why session left alive after rake db:drop?
I have
def current_order
if !session[:order_id].nil?
#current_order = Order.find(session[:order_id])
else
Order.new
end
end
helper_method :current_order
and after rake db:drop it gives me exception
Couldn't find Order with 'id' = my session number
>> session[:order_id]
=> 11
that means session still there. But Why?
Rails by default uses ActionDispatch::Session::CookieStore to store the session. Thus cleaning out the database does not remove any session data as it is held by the client.
Instead you would remove the cookies in the browser (in development) or change the secret key base to invalidate existing cookies.
See:
Ruby on Rails Security Guide

Ruby on Rails and Nokogiri: How to update attribute in database using a rake task

I am working on a rails app where I get an rss feed from BBC for news stories. I then store the news story's title, summary, and url from the rss feed. There is a blank column for images in my db at first, because I visit the url for the story and use nokogiri to scrape the main image's url afterwards through a rake task. Once I have the url for the image I try saving the item, with the newly updated attribute, to my database. However, whenever I run my rake task it doesn't work and I get errors. Here's the code:
task :getimg => :environment do
stories = FeedEntry.all
stories.each do |story|
url = story.url
doc = Nokogiri::HTML(open(url))
if doc.at_css(".full-width img")
img = doc.at_css(".full-width img")[:src]
story.image = img #my attempt to update the story's attribute
story.save! #does this save work?
elsif doc.at_css(".body-width img")
img = doc.at_css(".body-width img")[:src]
story.image = img # my attempt to update the story's attribute
story.save! #does this save work?
end
end
end
FeedEntry is my model for the news stories and here's the output in the console:
rake getimg --trace
** Invoke getimg (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute getimg
rake aborted!
Errno::ENOENT: No such file or directory # rb_sysopen - http://www.bbc.co.uk/news/world-africa-29184590#sa-ns_mchannel=rss&ns_source=PublicRSS20-sa
/Users/abhasarya/rails_projects/news_reader/lib/tasks/image_scraper.rake:9:in `initialize'
I know I am doing something wrong, and I'd greatly appreciate it if anyone can point me to the solution. Thanks!
You need to require 'open-uri' in your rake task
require 'open-uri'
doc = Nokogiri::HTML(open(url))

Geocoder ruby gem on demand?

I have a large database with 4+ million addresses/records.
The rake command (below) worked fine when the database was a small test set, but now with the large database it just simply stalls.
rake geocode:all CLASS=YourModel
2 questions:
1. Is there any simple method to have geocoder code a null/nil lat and long when the records are called (on the fly). I have a feeling that this would be hard.
2. Anyone else have problems with geocode-ing a large dataset and using the rake command?
Thanks!
Update:
I create pull request based on this answer and now you can use batch in geocoder:
rake geocode:all CLASS=YourModel SLEEP=0.25 BATCH=100
I would use this solution for large database, i take it from geocoder gem rake task:
You can refine this for your needs.
Some example create rake task:
namespace :geocode_my_data do
desc "Geocode all objects in my databse."
task all: :environment do
klass = User
klass.where(geocoded: false).find_each(limit: 100) do |obj|
obj.geocode; obj.save
end
end
end
$> rake geocode_my_data:all
Used below code and put it into my lib/tasks folder as geocode_my_data.rake
To run:
rake geocode:all CLASS=YourModel
Works great!
namespace :geocode_my_data do
desc "Geocode all objects without coordinates."
task :all => :environment do
class_name = ENV['CLASS'] || ENV['class']
sleep_timer = ENV['SLEEP'] || ENV['sleep']
raise "Please specify a CLASS (model)" unless class_name
klass = class_from_string(class_name)
klass.not_geocoded.find_each(batch_size: 100) do |obj|
obj.geocode; obj.save
sleep(sleep_timer.to_f) unless sleep_timer.nil?
end
end
end
##
# Get a class object from the string given in the shell environment.
# Similar to ActiveSupport's +constantize+ method.
#
def class_from_string(class_name)
parts = class_name.split("::")
constant = Object
parts.each do |part|
constant = constant.const_get(part)
end
constant
end

How to integrate my own scraper in Rails app?

I have just created a Rails app with a model app/models/post.rb and have written a scraper scrapers/base_scraper.rb (class BaseScraper) that collect data from the target site to the hash variable data. Now I want to insert values of data into the Post model. How to do it properly in Rails? I have heard smth about Rake but have no idea how to utilize it properly. Help me please!
Assuming that data stores just one post and that each of the key stored in the datahash are valid Post fields (column_name), you can do simply this:
Post.create(data)
If you want to launch the whole process from console, you can create a rake task under lib/tasks directory of your process with the following:
# scraper.rake
namespace :scraper do
desc "Run scraper"
task :run => :environment do
data = BaseScraper.your_collect_data_class_method
Post.create(data) if data
end
end
task :default => 'scraper:run'
And then run it from console as a rake task with rake scraper
Of course I also assume that scrapers dir is in your Rails load path.
If not, add it to your application.rbfile.
# application.rb
...
module YourApp
class Application < Rails::Application
...
config.autoload_paths += Dir["#{config.root}/scrapers/"]
...
end
end

Accessing a Model from js.erb file when precompiling

I have a Rails 3 app where I am trying to populate a javascript variable with every Nation in my database (less than 300 nations) as a JSON object. This is the relevant line in my nations.js.erb file:
_this.nations = <%= Nation.all.to_json :only => [:id], :methods => :text %>;
When I call my js file in a browser, /assets/users.js which does a require of the nations file, the _this.nations variable is populated perfectly. When I try to do a precompile I get the following:
$> rake assets:precompile
$> rake aborted!
uninitialized constant Nation (in nations.js.erb)
So my question is this: is it possible to reference the Nation model, or any model, from within the js.erb file for precompiling? I also tried using my NationsHelper but my error just changed to uninitialized constant NationsHelper.
I'm fairly new to RoR so if relevant information is needed that I haven't provided, please just ask.
If you have config.assets.initialize_on_precompile set to false somewhere then try enabling it
config.assets.initialize_on_precompile = true
Why don't you make the call in the controller
controller
#nations = Nation.all
nations.js.erb
_this.nations = <%= #nations.all.to_json :only => [:id], :methods => :text %>;

Resources