blank hash from rails controller? - ruby-on-rails

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.

Related

Applying filters to Rails model

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?

delete last value of a splitted string

I want to look into a hash but the last value should be there :
params send to controller
{
"user"=>{"email"=>"a#a.fr,
lol#lol.fr"}
method
def set_users
#users = params[:user][:email]
logger.debug "#{#users.split(",").each { |e| puts e }}"
end
logs
a#a.fr
lol#lol.fr
["a#a.fr", " lol#lol.fr"]
The point is that #each takes a value (["a#a.fr", " lol#lol.fr"]) which is not in the hash. How can I apply #each to the whole hash except on this value
I'd do:
#users.split(",")[0..-2]
Namely, take everything but the last.
So:
logger.debug #users.split(",")[0..-2].join(', ')
Seems you just need:
logger.debug #users
You should use the String#gsub method like this:
def set_users
email = params[:user][:email]
params[:user][:email] = email.gsub(/,.*/i, '')
end
Rewrite your method:
def set_users
#users = params[:user][:email].split(',')
#users.pop
end
Then you can use #users without last one and get last one's info by the return value from set_users method.

Ruby/Rails Iterate through array and save to db?

I want to put each string from #enc into each field of column_name as a value
#enc=["hUt7ocoih//kFpgEizBowBAdxqqbGV1jkKVipVJwJnPGoPtTN16ZAJvW9tsi\n3inn\n", "wGNyaoEZ09jSg+/IclWFGAXzwz5lXLxJTUKqCFIiOy3ZXRgdwFUsNf/75R2V\nZm83\n", "MPq3KSzDzLvTeYh+h00HD+5FAgKoNksykJhzROVZWbIJ36WNoBgkSoicJ5wx\nog0g\n"]
Model.all.each do |row|
encrypted = #enc.map { |i| i}
row.column_name = encrypted
row.save!
end
My code puts all strings from array #enc into a single field?
I do not want that.
Help
Rails by default won't allow mass assignment. You have to whitelist parameters you want permitted. Have you tried doing something like the following?
#enc.each do |s|
cparams = create_params
cparams[:column_name] = s
Model.create(cparams)
end
def create_params
params.permit(:column_name)
end
You will need to specify the column names you are saving to. By setting each column separately you can also avoid mass-assignment errors:
#enc=["hUt7ocoih//kFpgEizBowBAdxqqbGV1jkKVipVJwJnPGoPtTN16ZAJvW9tsi\n3inn\n", "wGNyaoEZ09jSg+/IclWFGAXzwz5lXLxJTUKqCFIiOy3ZXRgdwFUsNf/75R2V\nZm83\n", "MPq3KSzDzLvTeYh+h00HD+5FAgKoNksykJhzROVZWbIJ36WNoBgkSoicJ5wx\nog0g\n"]
model = Widget.new
column_names = [:column1, :column2, :column3]
#enc.each_with_index do |s, i|
model[column_names[i]] = s
end
model.save
I think you are looking for something like this:
#enc.each do |str|
m = Model.new
m.column_name = str
m.save
end

Ruby on Rails: See if a record exists that matches query on multiple columns

I'm developing an app that allows a user to answer a survey once, when they answer it (the first time) I'm capturing the users ip address and user agent (in the Test_users model).
What I'm trying to do is if the user navigates to the survey again they are redirected to a page telling them that they can only complete it once.
In the test controller, I'm thinking this should be:
def new
#Find the Test
#test = Test.find(params[:test_id])
if [[a record in test_users exists with the test id / ip address / user agent]]
redirect_to already_completed_path
end
end
I'm struggling with what this if statement, any help would be greatly appreciated
You can use the exists? method if you don't need the object for something else:
if Test.exists?(:test_id => params[:test_id], :ip_address => request.remote_ip, :user_agent => request.env['HTTP_USER_AGENT'])
redirect_to already_completed_path
end
Use the where clause and put all your conditions in it:
#test = Test.where("test_id = ? or ip_address = ? or user_agent = ?",
test_id, ip_address, user_agent)
This should work, assuming you are storing request.remote_ip and request.env['HTTP_USER_AGENT'] values in your tests table:
if #test.where(ip: request.remote_ip, user_agent: request.env['HTTP_USER_AGENT']).exists?
redirect_to already_completed_path
end
You Should be doing like this
In your Test Controller
def new
#Find the Test
#test = Test.find(params[:id]) #it should be `:id` not `:test_id` because the model wont be having its own foreign key in its own record
#test_user = TestUser.where("test_id = ? or ip_address = ? or user_agent = ?",
test_id, ip_address, user_agent)
if #test_user.exists?
redirect_to already_completed_path
else
redirect_to new_path

Rails: How to initialize an object with the attributes in strings?

Probably been working on this too long, sloppy design, or both. My issue is I have a model I wish to initialize. The object has like 52 attributes, but I'm only setting a certain ~25 depending on which object I've just scanned. When I scan an object I get the columns and match them up with a hash_map I've created.
Example Hash Map
This just matches the scanned text to their respective attribute name.
hash_map = {"Pizza."=>"pizza_pie","PastaBowl"=>"pasta_bowl","tacos"=>"hard_shell_taco","IceCream"=>"ice_cream","PopTarts"=>"pop_tart"}
What I want to do
menu = RestaurantMenu.new(pizza_pie => var1, pasta_bowl => var2, ...)
My only problem is in my code at the moment I have this...
t.rows.each do |r|
for i in 0..r.length-1
#hash_map[t.combined_columns[i]] => r.[i]
puts "#{hash_map["#{t.combined_columns[i]}"]} => #{r[i]}"
end
end
the puts line displays what I want, but unsure how to get that in my app properly.
Here is several ways to fix this:
hash_map = {"Pizza."=>"pizza_pie","PastaBowl"=>"pasta_bowl","tacos"=>"hard_shell_taco","IceCream"=>"ice_cream","PopTarts"=>"pop_tart"}
attributes.each do |attribute, element|
message.send((attribute + '=').to_sym, hash_map[element])
end
or like this:
class Example
attr_reader :Pizza, :PastaBowl #...
def initialize args
args.each do |k, v|
instance_variable_set("##{k}", v) unless v.nil?
end
end
end
for more details click here
I ended up doing the following method:
attributes = Hash[]
attributes["restaurant"] = tmp_basic_info.name
attributes["menu_item"] = tmp_basic_info.item_name
t.rows.each do |r|
for i in 0..r.length-1
attributes["other"] = t.other_information
attributes[hash_map[t.combined_columns[i]] = r[i]
end
row = ImportMenuItem.new(attributes)
row.save
end

Resources