Rails: Fetch feed entries from certain date with Feedjira - ruby-on-rails

How's it going SO'ers?
I've appended a Recent News section to the top of Users Dashboard, where it fetches news stories through Feedjira, saves the NewsEntry to the database (postgres) and then picks three random NewsEntries to display in the Dashboard#index view.
I've also created a rake task NewsEntry.update_from_feed(feed_url) to update the table with new NewsEntries scheduled to run once every 24 hours.
My problem, because it's a Recent News section I would like to fetch the NewsEntries that were published today (or yesterday; this could be a time as well). Eventually I'll add to the rake task to remove old articles and update the feed with newer articles. Right now I am getting an error trying to fetch entries on a certain date:
NoMethodError: undefined method `where' for #<Array:0x00007fcab2910d00>
NewsEntry
class NewsEntry < ApplicationRecord
def self.update_from_feed(feed_url)
feed = Feedjira::Feed.fetch_and_parse(feed_url)
add_entries(feed.entries)
end
private
def self.add_entries(entries)
today = Date.today
entries.where("published_at = ?", today) do |entry|
unless exists? :guid => entry.id
create!(
:title => entry.title,
:url => entry.url,
:published_at => entry.published,
:guid => entry.id
)
end
end
end
end
Thanks in advance for any help!

Related

Fetch Google Analytics for Model Instances in Ruby on Rails

I am trying to fetch the page views for each instance of our model Campaigns. After much Googling, I used this post as the basis of my work: http://gistflow.com/posts/398-pageviews-for-posts I am instead using the updated Legato gem.
I am having trouble fetching and saving to the database the pageviews for each Campaign.
Here is the modified code working from the gistflow post.
Rake task:
namespace :campaigns do
task :update_page_views => :environment do
google_analytics = GoogleAnalytics.new
#campaigns = Campaign.all
#campaign = Campaign.find(:all)
#campaigns.each do |campaign|
page_views = google_analytics.page_views(campaign)
campaign.update_attribute(:page_views, page_views) if page_views
end
end
end
Legato model:
class GoogleAnalytics
extend Legato::Model
metrics :pageviews
dimensions :page_path
attr_reader :profile
def page_views(campaign)
access_token = GoogleOauth2Installed.access_token
user = Legato::User.new(access_token)
profile = user.profiles.first
GoogleAnalytics.results(
profile,
:filters => {:page_path.eql => campaign.path},
:start_date => 5.years.ago.to_date,
:end_date => Date.today
).to_a.first.try(:pageviews)
end
end
However, I receive an error
undefined method `path' for #<Campaign:0xbf334a4>
If I change the filter line to:
:filters => {:page_path.eql => campaign},
then the task runs, but all of the campaigns have the same number of views which matches the total of all of the campaigns.
I played around with the GA Query tool mentioned in Getting query results with Legato gem
and can get a result I want with:
filters = ga:pagePath==/campaigns/6
However, even if I plug that into the code, the task still results with all of the campaigns having the same number which is the total of campaigns.
I have also looked at this answer How to pull Google Analytics stats? but do not have enough reputation yet to ask Severin to explain how to modify the query.
I have looked into the Impressionist gem but would like to make it work with GA as we would like to pull more GA data in the future.
Thanks so much for any help!!

RoR | how to find the next and previous based on a date

I'm trying to look up 1 instance of a model via a slug, which I can do via
#project = Project.where(:slug => params[:id]).first
But once I get the instance I want to find the next and previous instances of the model from a order of a column called publish which is a date.
how would I get the slug only of the previous and next instance of my arbitrary order by column?
::Edit::
Adding this to my modeled worked.
def previous(offset = 0)
self.class.select('slug').first(:conditions => ['published < ?', self.id], :limit => 1, :offset => offset, :order => "published DESC")
end
def next(offset = 0)
self.class.select('slug').first(:conditions => ['published > ?', self.id], :limit => 1, :offset => offset, :order => "published ASC")
end
I found this solution at Next, Previous Records Using Named Scope
Assuming your publish dates are unique something like this ought to work:
#project = Project.where(:slug => params[:id]).first
#prev_project = Project.where( "publish < ?", #project.publish ).
order( "publish DESC" ).
first
#next_project = Project.where( "publish > ?", #project.publish ).
order( "publish" ).
first
For #prev_project the where clause indicates all Projects before #project, the order lists them latest first (which puts the one right before #project at the top) and first limits the query to one result, i.e. the previous Project. The query for #next_project is the same but reversed. If publish isn't unique you'll have to sort on a second criterium as well.
However, you may want to consider not reinventing the wheel and using the very common gem acts_as_list, which would make this as simple as #project.higher_item and #project.lower_item.

Show content based on holidays

ruby 1.9.2p290
rails 3.1.1
I have these models:
class Recipe < ActiveRecord::Base
belongs_to :festivity
end
class Festivity < ActiveRecord::Base
has_many :recipes
end
I have the following field in the "recipes" table:
festivity_id
And the following datetime fields in the "festivities" table:
starts_at
ends_at
How to display the content based on festivities dates?
I started think in this static way:
class PagesController < ApplicationController
def home
#recipes_by_festivities = Recipe.where(:festivity_id => 4).all(:order => 'RAND()', :limit => 8)
end
end
For example: In Xmas period (about all december month), I want to show a recipe list with the festivity_id = 1. In Thanksgiving period I wanna just a list of recipes with festivity_id = 4.
Am I clear? Let me know if I not.
SOLUTION
#current_festivity = Festivity.find(:last, :conditions => ["? between starts_at AND ends_at", Time.utc(0,Time.now.month,Time.now.day,0,0,0)])
#recipes_by_festivities = Recipe.where(:festivity_id => #current_festivity).all(:order => 'RAND()', :limit => 8)
What I would do is create a "name" field in the festivities table, then use the holidays gem to determine if there's a holiday on a specific date.
Holdays.on(Date.today)
Which will return a list of hashes: each hash has a name key. Then you could use that to look up the correct Festivity object current_festival = Festivies.where(:name => Holdays.on(Date.today)[0][:name]) and from there get the recipes: current_festival.recipes
This assumes starts_at and ends_at are saved with the same year (0), except if the period is in the middle of two years (Christmas time, for example): in that case, the ends_at year must be 1.
Festivity.create(name: 'Christmas time', starts_at: Time.utc(0,12,25,0,0,0), ends_at: Time.utc(1,1,6,23,59,59))
Festivity.create(name: 'Ferragosto', starts_at: Time.utc(0,8,15,0,0,0), ends_at: Time.utc(0,8,15,23,59,59))
Recipe.create(festivity: Festivity.find_by_name('Periodo natalizio'))
Recipe.create(festivity: Festivity.find_by_name('Ferragosto'))
# Searching for festivities today
Recipe.includes(:festivity).where(['? BETWEEN festivities.starts_at AND festivities.ends_at', Time.utc(0,Time.now.month,Time.now.day,12,0,0)]).all
# Searching for festivities on 15 August (in Italy there is a festivity that is called Ferragosto)
Recipe.includes(:festivity).where(['? BETWEEN festivities.starts_at AND festivities.ends_at', Time.utc(0,8,15,12,0,0)]).all
# Searching for festivities on 28 December
Recipe.includes(:festivity).where(['? BETWEEN festivities.starts_at AND festivities.ends_at', Time.utc(0,12,28,12,0,0)]).all
And this is a possible implementation of a function:
def recipes_on(day, month)
Recipe.includes(:festivity).where(['? BETWEEN festivities.starts_at AND festivities.ends_at', Time.utc(0,month,day,12,0,0)]).all
end
Since you want to find recipes by festivities, you can do this:
def home
festivity_today = some_custom_festivity_lookup(Time.now)
if !festivity_today.nil?
#recipes = Recipe.where(festivity_id: festivity_today.id).limit(8)
else
#recipes = Recipe.limit(8)
end
end

Sort by date using acts_as_solr

I have gotten sorting working from my rails application using acts_as_solr for text fields, as seen below with Title.
I am having problems getting it to work for date.
My model has the following
class Article < ActiveRecord::Base
acts_as_solr :fields[:title, {:title_s=> :string}, {:created_at_d => :date}]
def title_s
self.title
end
def created_at_d
self.created_at
end
The following is being sent to the solr server:
path=/select params={wt=ruby&rows=10start=0&sort=created_at_d_d+asc&fl=pk_i,score&q=(+searchtext)..........
The solr code
Article.paginate_all_by_solr(searchString, :order=> "created_at_d asc", :page = page, :per_page => results_per_page, :total_entrieds => count)
Is there something obvious I am doing wrong? I am not sure that the {:created_at_d => :date} in the model is the correct way to set up the index for dates.
When I just coin it off of :created_at, I get the error around tokenized fields similar to that when I tried to sort against :title.
Something was wrong with the index.
When I went into script/console and ran
Article.rebuild_solr_index
It did not index the date correctly.
I created a rake task from with the following site.
http://henrik.nyh.se/2007/06/rake-task-to-reindex-models-for-acts_as_solr
When I ran
>rake solr:reindex
The index was created correctly and the date sorting started working.

Creating "feeds" from multiple, different Rails models

I'm working on an application that has a few different models (tickets, posts, reports, etc..). The data is different in each model and I want to create a "feed" from all those models that displays the 10 most recent entries across the board (a mix of all the data).
What is the best way to go about this? Should I create a new Feed model and write to that table when a user is assigned a ticket or a new report is posted? We've also been looking at STI to build a table of model references or just creating a class method that aggregates the data. Not sure which method is the most efficient...
You can do it one of two ways depending on efficiency requirements.
The less efficient method is to retrieve 10 * N items and sort and reduce as required:
# Fetch 10 most recent items from each type of object, sort by
# created_at, then pick top 10 of those.
#items = [ Ticket, Post, Report ].inject([ ]) do |a, with_class|
a + with_class.find(:all, :limit => 10, :order => 'created_at DESC')
end.sort_by(&:created_at).reverse[0, 10]
Another method is to create an index table that's got a polymorphic association with the various records. If you're only concerned with showing 10 at a time you can aggressively prune this using some kind of rake task to limit it to 10 per user, or whatever scope is required.
Create an Item model that includes the attributes "table_name" and "item_id". Then create a partial for each data type. After you save, let's say, a ticket, create an Item instance:
i = Item.create(:table_name => 'tickets', :item_id => #ticket.id)
In your items_controller:
def index
#items = Item.find(:all, :order => 'created_on DESC')
end
In views/items/index.erb:
<% #items.each do |item| %>
<%= render :partial => item.table_name, :locals => {:item => item} %><br />
<% end %>

Resources