Rails loop through records in model - ruby-on-rails

I have 2 hstore columns (parameters and keys) defined in my PostgeSQL database. I want to get a list of keys and have defined a method for it in the model:
def self.keys_list
logs = self
list = Log.column_names - %w{id parameters extras}
logs.each do |log|
log.parameters.present? ? list << log.parameters.keys : list << []
log.extras.present? ? list << log.extras.keys : list << []
end
list = list.flatten.uniq
return list
end
But when I try using it, I get the following error:
NoMethodError: undefined method `each' for #<Class:0x00000004b630b0>
Can anyone suggest where the error is or how to do it some other way?

ActiveRecord::Base does not define an .each method. You need to add in a call to all, like so:
all.each do |log|
#...
end
This should make both Log.keys_list and Log.where(name: "Peeyush").keys_list work.

Related

How to pass methods to Ruby Map

I have the following code:
wedding = Wedding.where(location_id: user_params[:locationId])
wedding.map(&:guests).each do |member|
user_ids << member.ids
end
In my case :guests is a active record table, but I have a couple that I would like to pass thru map to generate the user_ids
So it would be array of methods like this, that I would like to pass: [guests, bride, etc etc]
It would be even better if I could pass the whole array, but otherwise if I can step through the array of methods that would be great too.
Any ideas?
EDIT:
I'm trying this with no luck.. I get: NameError (wrong constant name guests):
roles = ["guests"]
wedding = Wedding.where(location_id: user_params[:locationId])
roles.each do |role|
clazz = Kernel.const_get(role)
wedding.map(&:clazz).each do |member|
user_ids << member.ids
end
end
Below, i pass an array of methods to members of the array weddings:
weddings = Wedding.where(location_id: user_params[:locationId])
# array with methods you're interested in
methods=[:guests, :bride]
# looping through the weddings array
weddings.each do |wedding|
# looping through the methods array
methods.each do |method|
# for each wedding, passing every method to the wedding
members=wedding.public_send(method)
members.each do |member|
# storing the values
user_ids << member.ids
end
end
end

Calling model methods using a variable Rails

Rails 5.2
I have a Catalog model, with the following methods:
def current_items
....
end
def sales_items
....
end
There are more than a dozen methods, and I would like to do, in my helper, is to define an array
categories = ['current', 'sales', ....]
categories.each do |category|
m = "{category}_items"
#items = Catalog.m
...
end
But, I am getting an error:
undefined method 'm' for Catalog:Class
Any idea if this can be done?
Please try below code :-
class Catalog < ActiveRecord::Base
def self.current_items
puts "from current_items"
end
def self.sales_items
puts "from sales_items"
end
end
Then call using :-
if public
m = "#{category}_items"
#items = Catalog.public_send(m)
if private
m = "#{category}_items"
#items = Catalog.send(m)
thanks :)
Try public_send to call the public methods in class, use send if you want to call private methods as well but avoid using send if not needed
m = "#{category}_items"
Catalog.public_send(m)
Give it a try!

Iterate through array of column names to pass to uniq.pluck()?

I have multiple columns I need to pull unique values from and compile an array of each unique value. Using uniq.pluck(:column_name) works, but how do I iterate over an array of column names?
react = []
fields = [reactivity_1, reactivity_2, reactivity_3, reactivity_4]
fields.each do |field|
puts "Parsing #{field}"
Raw.all.uniq.pluck(field).each do |r|
unless react.include? r
puts "Adding #{r} to Array."
react << r
else
puts "#{r} Exists."
end
end
end
Error:
NameError: undefined local variable or method `reactivity_1' for main:Object
You will need to make the column names strings or symbols, like this Ruby thinks it is a local varaible or method.
react = Set.new
fields = [:reactivity_1, :reactivity_2, :reactivity_3, :reactivity_4]
fields.each do |field|
puts "Parsing #{field}"
Raw.all.uniq.pluck(field).each do |r|
react << r
end
end
If you want to make sure that a collection does not contain duplicate, you can use a Set:
require "set"
set = Set.new
set << "foo"
set << "bar"
set << "bar"
puts set.size #> 2
I've rewritten your code sample to use Set.
Can you describe what you are trying to achieve? Perhaps there is an easier way to get the data out of the DB.

Rails Search with query

I want to filter jobs on the parameter passed onto the model, currently search works flawlessly without query passed into the model, but when I type query it doesn't return anything. How can I perform this query with query and criteria.
results << model.with_query(query).where(criteria). any idea would be really appreciated.
module Refinery
class SearchEngine
# How many results should we show per page
RESULTS_LIMIT = 100
# Perform search over the specified models
def self.search(query, job_region, job_division, country, job_type, page = 1)
results = []
Refinery.searchable_models.each do |model|
criteria = {:job_region => job_region,
:job_division => job_division,
:country => country,
:job_type => job_type
}.select { |key, value| value.present? }
if query.present?
results << model.with_query(query).where(criteria)
else
results << model.limit(RESULTS_LIMIT).where(criteria)
end
end
results.flatten[0..(RESULTS_LIMIT - 1)]
end
end
end
The problem here is that the method .with_query(qry) returns an Array. You want to do chain-scoping, so you must use scopes that returns ActiveRecord::Relation objects.
model.with_query(query)
# returns an Array
model.with_query(query).where(criteria)
# calling .where on an Array object => NoMethodError
model.where(criteria)
# returns an ActiveRecord::Relation
model.where(criteria).with_query(query)
# calls the query on an AR::Relation object, which is doable
Short version: Change this:
results << model.with_query(query).where(criteria)
To this:
results << model.where(criteria).with_query(query)

Rails Array Conditions Query

I've written the following method to combine the References of Sections model and it's children:
def combined_references
ids = []
ids << self.id
self.children.each do |child|
ids << child.id
end
Reference.where("section_id = ?", ids)
end
But section.combined_references returns the following error:
Mysql2::Error: Operand should contain 1 column(s): SELECT `references`.* FROM `references` WHERE (section_id = 3,4)
It seems to have collected the correct values for ids, have I structured the query incorrectly?
Transform last line to:
Reference.where(section_id: ids)
and it should produce:
SELECT `references`.* FROM `references` WHERE section_id IN (3,4)
And you can shorten your code by one line with :
ids = []
ids << self.id
to
ids = [self.id]
it's invalid statement
WHERE (section_id = 3,4)
correct would be
WHERE (section_id in (3,4))
Please use:
Reference.where(:section_id => ids)
You can try something like this instead:
def combined_references
ids = self.children.map(&:id).push(self.id)
Reference.where(section_id: ids)
end
You can also query the database with:
Reference.where("section_id in (?)", ids)
The following has the most readability in my opinion:
def combined_references
Reference.where(section_id: self_and_children_ids)
end
private
def self_and_children_ids
self.children.map(&:id).push(self.id)
end

Resources