Rails App Movies API - Heroku - ruby-on-rails

I have a Rails Movie App which will potentially use APIs from other websites to fill my database.
I am using the TMDB.org API (I already have an API Key) to extract, for now lets say the Title and Description of a movie.
How would I go by extracting information from the tmdb site to my site and display the information in <% #movie.title %> and <% #movie.description %>
The information taken will need to be placed in my PostgreSQL Database using Heroku
So thats one question
The other question is how would I do this without running a method for every movie in the TMDB database
For Example, using the Ruby-TMDB Gem, instead of running
TmdbMovie.find(:title => "The Social Network", :limit => 10, :expand_results => true, :language => "en")
and
TmdbMovie.find(:title => "The Dark Knight Rises ", :limit => 10, :expand_results => true, :language => "en")
for every movie I want in my database (which is every movie in the TMDB Database), what would I run to GET ALL Movies.
And then Display them in my movies :show page
To sum it all up, how to I get database information from TMDB.org to my rails app and display information from a TMDB Movie :show page to my movie :show page, using the Ruby-TMDB Gem IN Heroku? Would there be a rake task, if so what would it be?
Many Thanks!

There are 2 problems you wish to tackle.
How and where in my rails app should I pull the data?
Yeah this can be accomplished with rake. Add a new rake file lib/tasks/tmdb.rake
namespace :db do
task :pull_tmdb_data => :environment do
Tmdb.api_key = "t478f8de5776c799de5a"
# setup your default language
Tmdb.default_language = "en"
# find movies by id
#movie = TmdbMovie.find(id: 123)
Movie.create title: #movie.title, description: #movie.description
# find movies in groups
#movies = TmdbMovie.find(:title => 'Iron Man')
#movies.each do |movie|
Movie.create title: movie.title, description: movie.description
end
end
end
And now everytime you want to populate your db with tmdb you can simply run rake db:pull_tmdb_data
What are the necessary queries to pull all the movies from tmdb?
By glancing over their api there is no shortcut to duplicating the database, if you want to duplicate it your best bet may be to contact them directly. You can brute force it by trying every possible id for movies but beware that they do throttle you. Below is a quote from their website.
We do enforce a small amount of rate limiting. Please be aware that should you exceed these limits, you will receive a 503 error.
30 requests every 10 seconds per IP
Maximum 20 simultaneous
connections
It may be worth considering if you really need to duplicate tmdb. When tmdb is adding new movies and fixing errors in their data your database will be outdated as a result you will face a slew of data integrity issues which will be hard to resolve.

Related

Creating a multiple choice test on Rails using a hash table

I'm in a tech summer camp and our teacher is showing us how to use Ruby on Rails. I told my teacher want I wanted to make and he told us to post here because it's important to learn from other developers.
I was looking on the site and found this question that is similar to what I want to do for my project. I want my friends to be able to read a few pages of text and then do a short test to make sure they were paying attention.
I want to make a hash table like the question I linked above but I don't know where to put it in my app! I would also like to tie it to users somehow so I can see which of my friends completed the test or not.
So far I have made user, question and answer models and would like to use a hash table like this test my fellow students.
# Question:
{ :question_id => 1,
:text => 'What is Minecraft?',
:answers => # Answers:
[{:answer_id => 1, :text => 'A game'},
{:answer_id => 2, :text => 'A food'},
{:answer_id => 3, :text => 'A store'} ],
:correct_answer_id => 1 }
Can someone tell me where I need to put this in my app and how I can save it to a database? My teacher said it is okay if people tell us how to do stuff as long as we tell him in our write up.
If you have related your answers with a has_many relationship to your question you can create answers with questions like this:
question = Question.create!(text => 'What is Minecraft?')
question.answer.create!(:text => 'A game')
question.answer.create!(:text => 'A food')
...
Ids will usually given out by the database, just don't need to define them yourself.

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!!

thumbs_up Rails gem's "at_least" and "order" methods not doing anything

I'm using the thumbs_up gem in Rails to create a voting system. In one of my controllers, I have a model called Superlative that acts_as_voteable, and I'm trying to filter out the objects with at least one vote.
Based on the documentation and online resources, this should work:
def most_votes
#most_votes = Superlative.tally(
{ :at_least => 1,
:limit => 10,
:order => 'vote_count desc'
})
end
But I get all the records in the Superlative model back, even ones with 0 votes. Also, the ordering doesn't seem to work either. Not matter if I put desc or asc the ordering is always desc.
I Googled everywhere but no one seems to have the same problem.
Here are some relevant app details:
Using thumbs_up (0.6.5)
Using rails (3.2.13)
ruby 1.9.3p429
Update: additional info
I tried running the above controller code (that's all for that action) in the console, and again, all records were returned, including those with 0 votes.
Also, view code below:
- provide(:title, "Best Superlatives")
#superlatives
%h1.title Superlatives (Most Votes)
%table.table.table-hover
%thead
%tr
%th Name
%th Most Likely ...
%th Votes
%th Vote!
%tbody
= render #most_votes
%br/
If that doesn't work it could be that you are overwriting the content of the variable #most_votes at some point before you draw it on your views.
Try to go into the rails console by running
bundle exec script/rails console
Once you are in the console try to run:
#most_votes = Superlative.tally(
{ :at_least => 1,
:limit => 10,
:order => 'vote_count desc'
})
And now check the content of #most_votes, you should see the votes which has at least 1 vote, with the right order, I'm pretty sure the gems works fine on these queries since I never had any problem with it and its being used by many developers on production environment.
If after doing that you confirm that the gem is working fine, try to update your question with the complete controller code, and the complete view code so we can help to debug the issue.

In Rails - How to have one query that has multiple queries?

In have 3 models here:
projects
threads (project_id)
thread_participations (thread_id, read boolean)
Right now I have a list of the user's projects, and the list shows how many threads are unread per project. The huge problem here is that if the user has several projects (which all users do) it causes the DB to get hit with several queries, one per project.
I would like to use Rails to build a query, that with one DB hit, returns an unread count for each of the user's project.
Here's what I use today in the view:
<% #projects.each_with_index do |project, i| %>
<%=project %>: <%= Thread.unread(current_user,project).count %>
<% end %>
And in the thread Model:
scope :unread, lambda { |user,project|
includes(:project,:thread_participations).where(:project_id => project.id, :thread_participations => {:read => false, :user_id => user.id})
}
Any suggestions on how to do this? Also which model should this live in? Maybe the user's model since it is not project or thread specific?
Thanks
There are a couple of ways to structure this query, but here is one.
You can perform this in a single query and then loop over the results. I would first create a scope on thread participations for unread for a certain user. Then use the scope and include all threads and projects, group by the project id (so that you are getting unread threads for that project) and then count the number of unread threads by counting threads.id:
class ThreadParticipations
scope :unread, lambda{ |user| where(user_id: user.id, read: false) }
end
ThreadParticipations
.unread(current_user)
.includes(:thread => :project)
.group('projects.id')
.count('threads.id')
=> { 10 => 15, 11 => 10 }
# project(10) has 15 unread threads and project(11) has 10 unread threads

Location based search in Rails using geokit problem

I have a rather complex (or so it seems) geokit based location search on my site. In short, I have a model named "Campaigns" that belongs to another model called "Businesses". When I am searching on the site, users are searching for "Campaigns", but I want all appropriate models to show up in the results if they search for that Campaigns business name. For this I am doing a joins in the search.
I additionally have the geokit plugin and gem installed so that users can get results for these searches only within a set distance from the origin location (which they provide). However, I am getting strange results when I add this location functionality into the site.
If I use the following search (simplified for brevity, but tested in the console):
Campaign.find(:all,
:joins => :business,
:conditions => ['businesses.name LIKE ?', "%Koo Koo Roo%"]
)
I get the appropriate result, which is:
[#<Campaign id: 12, user_id: 4, business_id: 8, created_at: "2011-01-14 16:22:31", updated_at: "2011-01-14 16:25:20", lat: #<BigDecimal:2ad295a9eda8,'0.34154891E2',18(18)>, lng: #<BigDecimal:2ad295a9ed08,'-0.118358834E3',18(18)>>]
But if I try to add geokit based location search parameters onto this search, like so:
Campaign.find(:all,
:joins => :business,
:origin => "90066",
:within => 25,
:conditions => ['businesses.name LIKE ?', "%Koo Koo Roo%"]
)
I get the following result:
[#<Campaign id: 8, user_id: 4, business_id: 8, created_at: "2011-01-14 16:25:20", updated_at: "2011-01-14 16:25:20", lat: #<BigDecimal:2ad29933e618,'0.34154891E2',18(18)>, lng: #<BigDecimal:2ad29933e578,'-0.118358834E3',18(18)>>]
Which is almost identical. The only difference is, for the second result, it seems to be passing the business_id as the Campaign id. I have verified this twice, and both times it is the same thing, the campaign id gets replaced with the business_id.
I should mention, that this is true no matter what :within distance i enter.
What am I doing wrong here? Am I missing something? I can't seem to figure it out, it all looks sound to me, but apparently not! I don't understand how the results could be screwed up like this by geokit.
in my models I simply have:
Business.rb
has_many :campaigns
Campaign.rb
belongs_to :business
Any help would be appreciated. Am I missing some sort of association? I don't have geokit caching turned on.
Thanks!
It's because the "id" field is being overwritten by dodgy join code. When you join, you've got two "id" fields (one for business and one for campaign). without an explicit instruction as to which is "the" id, the DB guesses.
Unfortunately, the one of the versions of rails has a bug where it did not explicitly state that the main Active Record id (in this case Campaign.id) was the id that counts... and the db was guessing the wrong one, overwriting id with the Business.id.
You've already discovered the easy (but more hacky) fix... the other is upgrading rails.

Resources