Applying filters to Rails model - ruby-on-rails

def show_category
category_selected = params[:genre]
all_movies = Movie.all
#movies_in_category = all_movies.where(:category => category_selected)
puts "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
puts category_selected
puts #movies_by_category.length
end
I have the above controller function which gets called with a parameter.
params[:genre]
the above line print out the parameter just fine.
all_movies = Movie.all
#movies_in_category = all_movies.where(:category => category_selected)
But the above 2 lines of code don't seem to be executed at all (I don't see the SQL queries for the above 2 lines being printed on the Rails console.
I also tried this but still couldn't see the SQL on the Rails console:
#movies_in_category = Movie.where(:category => category_selected)
What am I doing wrong here?

Related

undefined method `set' for nil:NilClass in Rails even though similar code works in irb

The following code works fine in IRB (Interactive Ruby Shell):
require 'prometheus/client'
prometheus = Prometheus::Client.registry
begin
#requests = prometheus.gauge(:demo, 'Random number selected for this users turn.')
rescue Prometheus::Client::Registry::AlreadyRegisteredError => e
end
#requests.set({name: "test"}, 123)
test = #requests.get name: "test"
puts 'output: ' + test.to_s
2.4.0 :018 > load 'test.rb'
output: 123.0
=> true
2.4.0 :019 >
However, when I put the same code into my Ruby on Rails controller, the second time the user uses the application, the following error is returned:
undefined method `set' for nil:NilClass
Can someone tell me when I'm doing wrong? Thank you.
require 'prometheus/client'
class RandomnumbersController < ApplicationController
def index
#randomnumbers = Randomnumber.order('number DESC').limit(8)
#counter = 0
end
def show
#randomnumber = Randomnumber.find(params[:id])
end
def new
end
def create
#randomnumber = Randomnumber.new(randomnumber_params)
prometheus = Prometheus::Client.registry
begin
#requests = prometheus.gauge(:demo, 'Random number selected for this users turn.')
rescue Prometheus::Client::Registry::AlreadyRegisteredError => e
end
#requests.set({name: "test"}, 123)
test = #requests.get name: "test"
#randomnumber.save
redirect_to #randomnumber
end
private
def randomnumber_params
params.require(:randomnumber).permit(:name, :number)
end
end
Because there is no #requests for :demo argument.
When ORM cannot find any info in db it returns nil (NilClass)
and You're trying to do:
#requests.set({name: "test"}, 123)
it's interpreted like:
nil.set({name: "test"}, 123)
why it's causes this issue in second time?
cuz Your code changes #requests name attribute to be test and seems like :demo is not test or maybe in another part of Your app You're replacing/deleting data in database that makes: #requests = prometheus.gauge(:demo, 'Random number selected for this users turn.') to return nil
Solution:
in code level add this fixes to avoid such unpredictable situations (check for nil) :
unless #requests.nil?
#requests.set({name: "test"}, 123)
test = #requests.get name: "test"
end

Inconsistent results from active-record query

This is my Person model which has the following query in a method:
def get_uniq_person_ids
uniq_person_ids = select('person_id').where(:state => '1').uniq
uniq_person_ids
end
My Test is as follows:
def test_uniqueness
Person.delete_all
assert_equal(0, Person.count)
# ..... Adding 8 rows to the database with 2 unique person_id.....
pids = Person.get_uniq_person_ids
assert_equal(pids.size, 2)
end
Test fails with the following:
Failure:
<8> expected but was
<2>.
There are 8 rows but only 2 unique person_id in the table.
This is what I tried:
puts pids before assert. It prints only 2 objects. Test fails with the above message.
binding.pry right before the query. Size is 2 which is expected and the test passes this time.
Why is the result so inconsistent? Is it a timing issue?
Note: I am using sqlite as my database.
Okay, so I am not sure what the actual issue was but the following solved it:
def get_uniq_person_ids
uniq_person_ids = select('person_id').where(:state => '1').uniq
uniq_person_ids = uniq_person_ids.map(&:person_id)
uniq_person_ids
end
I added the line uniq_person_ids = uniq_person_ids.map(&:person_id) to create the array of person_ids.

blank hash from rails controller?

I have a custom method in my rails app that looks like this below.
I have tested the sql in the rails console and it returns a hash like this id => vu.
def self.vu ids
results = User.select('tests.dpi, sum(worker) as vu')
.joins{tests}
.where("tests.dpi in (?)", ids)
.group('tests.dpi')
hash = {}
results.each {|record| hash[record.dpi] = record.vu}
hash
end
For show in my controller I have this:
def show
ids = User.find(params[:id])
logger.debug "test: #{ids.id}"
#See ID at this point and SQL query runs
vu = Hash.new
vu =User.vu ids.id
logger.debug "value: #{vu}"
#Blank
vu = vu[ids.id]
logger.debug "value: #{vu}"
#blank no hash value?
end
I can see the SQL query running correctly, and it works in console, but it doesn't set a value in the hash? What am I obviously missing? Thank you.

Running GET Request Through Rails on separate thread

I have a get request that retrieves JSON needed for graphs to display on a page. I'd do it in JQuery, but because of the API that I am using, it is not possible -- so I have to do it in rails.
I'm wondering this: If I run the get request on a separate thread in the page's action, can the variable then be passed to javascript after the page loads? I'm not sure how threading works in rails.
Would something like this work:
Thread.new do
url = URI.parse("http://api.steampowered.com/IDOTAMatch_570/GetMatchHistory/v001/?key=#{ENV['STEAM_WEB_API_KEY']}&account_id=#{id}&matches_requested=25&game_mode=1234516&format=json")
res = Net::HTTP::get(url)
matchlist = JSON.parse(res)
matches = []
if matchlist['result'] == 1 then
matchlist['result']['matches'].each do |match|
matches.push(GetMatchWin(match['match_id']))
end
end
def GetMatchWin(match_id, id)
match_data = matchlist["result"]["matches"].select {|m| m["match_id"] == match_id}
end
end
end
Given that the above code is in a helper file, and it then gets called in the action for the controller as such:
def index
if not session.key?(:current_user) then
redirect_to root_path
else
gon.winlossdata = GetMatchHistoryRawData(session[:current_user][:uid32])
end
end
The "gon" part is just a gem to pass data to javascript.

Sending Simple Email in Rails

I've read a few questions and http://guides.rubyonrails.org/action_mailer_basics.html on how to send emails with Rails but can't seem to get it to work within the context of my current application.
I had an existing emailer.rb with a couple of methods that were identical apart from the parameters they accepted were named differently so I copied their format:
def quotation_notification(q)
#recipients = q.recipient_email
#from = q.partner_name + "<#{q.partner_email}>"
#subject = "New Quotation from " + q.partner_name
#body[:q] = q
end
I then created a new view file in emailers named quotation_notification.rhtml which just contains text for the moment.
I am then calling the function from inside a different controller and sending hardcoded parameters for now:
q = QuotationEmail.new(:recipient_email => 'martin#domain.co.uk', :partner_name => 'Martin Carlin', :partner_email => 'martin#domain.co.uk')
# send email
Emailer.deliver_quotation_notification(q)
Then finally, I created a new model for QuotationEmail
class QuotationEmail
def initialize(recipient_email, partner_name, partner_email)
#recipient_email = recipient_email
#partner_name = partner_name
#partner_name = partner_email
end
end
The error I get is ArgumentError (wrong number of arguments (1 for 3))
Eventually I'll be sending more parameters and hopefully attaching a pdf aswell but just trying to figure out why this isn't working first.
You are getting this error because while initialising QuotationEmail object though you think you're passing 3 params you're essentially passing only one parameter which is a hash. And initialize is expecting 3. See example below
class A
def initialize(a,b=1,c=2)
puts a
puts b
puts c
end
end
a = A.new(:recipient_email => 'martin#domain.co.uk', :partner_name => 'Martin Carlin', :partner_email => 'martin#domain.co.uk')
#=> {:recipient_email=>"martin#domain.co.uk", :partner_name=>"Martin Carlin", :partner_email=>"martin#domain.co.uk"}
#=> 1
#=> 2
If you're trying to use named parameters instead you'd need to redefine your initialize as
def initialize(recipient_email:a,partner_name:b,partner_email:c)
and invoke it as below -
a = A.new(recipient_email:'martin#domain.co.uk', partner_name:'Martin Carlin', partner_email:'martin#domain.co.uk')

Resources