Display Json in view - ruby-on-rails

Im having problems trying to display in my view information comming from a json file. I have already parse it.
Here is my error:
When assigning attributes, you must pass a hash as an argument.
Extracted source (around line #23):
21 # #new_member.constructors = [driver['Constructors'][0]['name']]
22 # #new_member.points = [driver['points']]
23 #new_member.from_json(json)
#members << #new_member
end
# #new_member.constructors = [driver['Constructors'][0]['name']]
# #new_member.points = [driver['points']]
#new_member.from_json(json)
#members << #new_member
end
This is my controller:
require 'open-uri'
require 'json'
url = "http://ergast.com/api/f1/2014/driverStandings.json"
data = JSON.parse(open(url).read)
standings = data['MRData']['StandingsTable']['StandingsLists'][0]['DriverStandings']
#members = Array.new
standings.each do |driver|
json = standings.to_json
#new_member = Member.new
# #new_member.position = [driver['position']]
# #new_member.givenName = [driver['Driver']['givenName']]
# #new_member.familyName = [driver['Driver']['familyName']]
# #new_member.constructors = [driver['Constructors'][0]['name']]
# #new_member.points = [driver['points']]
#new_member.from_json(json)
#members << #new_member
If I uncommented the lines in the controller and delete these lines
#new_member.from_json(json)
json = standings.to_json
I get the following in the view
Name: ["Lewis"]
Name: ["Nico"]
That view is really close but is not what i need, I need the data without [" "],
so the view that I need is something like:
1 Lewis Hamilton Mercedes 384
Thanks in advance.

Alternative 1
Change the line:
#new_member.givenName = [driver['Driver']['givenName']]
into:
#new_member.givenName = driver['Driver']['givenName']
removing the external [ and ], so that the field #new_member.givenName that you're populating becomes a string rather than an array containing one string.
Alternative 2
Is it possible that, when looping through the standings hash, the driver temp variable is a Hash?
In this case it may be sufficient to do:
#members = Array.new
standings.each do |driver|
#members << Member.new(driver)
end
Bonus: you probably don't need to assign an instance variable #new_member, that gets overwritten at each iteration of the loop

Related

Extract Substring from String / Ruby

I get the datas from a variable called "apps".
And I have this datastructure:
{"id"=>001,
"name"=>"test01",
"users"=>
[{"id"=>01,
"name"=>"test02"},
{"id"=>02,
"name"=>"test03"}]}
How can I extract the namevalues from the users substring?
I have tried
apps.each do |test|
data = Hash.new
data['id'] = test['id']
data['name'] = test['name']
data['username'] = test['users.name']
userdata = data
userdata.each do |row|
File.write('test.yaml', row.to_yaml)
end
end
But that doesn't work.
desired output would be:
{"id"=>"01", "name"=>"test02","id"=>"02", "name"=>"test03"}
you just need to require 'yaml' in order to use it on Hash/Array classes, you don't need to iterate over array or hash, to_yaml already handles this for you.
require 'yaml'
data = {"id"=>001,
"name"=>"test01",
"users"=>
[{"id"=>01,
"name"=>"test02"},
{"id"=>02,
"name"=>"test03"}]}
File.write('test.yml', data["users"].to_yaml)

rails - get the SQL of a model save

I need to be able to output the SQL UPDATES that would be generated by Rails, without actually running them or Saving the records. I will be outputting the SQL updates to a file instead.
Is there a way to do this in Rails, without using string interpolation?
Is it possible to do something like the following:
p = Post.where (something)
p.some_value = some_new_value
p.to_sql??? # how to generate the update statement
rather than:
"UPDATE TABLE SET field_1 = #{new_field} WHERE ID = " etc etc
Took from #R.F. Nelson and wrap it to a method. You could just calling to_update_sql with your model as the argument to get the SQL.
def to_update_sql(model)
return '' if model.changes.empty?
table = Arel::Table.new(model.class.table_name)
update_manager = Arel::UpdateManager.new(model.class)
update_manager.set(model.changes.map{|name, (_, val)| [table[name], val] })
.where(table[:id].eq(model.id))
.table(table)
return update_manager.to_sql
end
post = Post.first
post.some_value = xxxx
to_update_sql(post)
# => UPDATE `posts` SET `some_value` = xxx WHERE `posts`.`id` = 1
Taken from this post:
You can achieve this goal with AREL:
# Arel::InsertManager
table = Arel::Table.new(:users)
insert_manager = Arel::InsertManager.new
insert_manager.into(table)
insert_manager.insert([ [table[:first_name], 'Eddie'] ])
sql_transaction = insert_manager.to_sql
File.open('file_name.txt', 'w') do |file|
file.write(sql)
end
# Arel::UpdateManager
table = Arel::Table.new(:users)
update_manager = Arel::UpdateManager.new
update_manager.set([[table[:first_name], "Vedder"]]).where(table[:id].eq(1)).table(table)
sql_transaction = update_manager.to_sql
File.open('file_name.txt', 'w') do |file|
file.write(sql)
end
Here you can find all Arel managers, like delete_manager.rb, select_manager.rb and the others.
Good read: http://jpospisil.com/2014/06/16/the-definitive-guide-to-arel-the-sql-manager-for-ruby.html

Array of hashes is overriding data directly to array

I want to make an array of hashes. But the problem is after first iteration when code goes to next line then it directly replaces the content of array.
#item_name =[]
item = {}
#invoiceinfo.each do |invoice|
item[:name] = Invoiceinfo.find(#invoiceinfo.id).item.name
item[:desc] = Invoiceinfo.find(#invoiceinfo.id).desc
item[:unit_price] = Invoiceinfo.find(#invoiceinfo.id).unit_price
byebug
#item_name.push (item)
end
This is what i am getting
after first iteration suppose i have this data
#item_name = [{:name=>"usman", :desc=>"sample ", :unit_price=>100}]
As soon as next line is executed it directly changes #item_name(name variable)
After executing item[:name] = Invoiceinfo.find(#invoiceinfo.id).item.name
the content of the #item_name is changed
#item_name = [{:name=>"next_name", :desc=>"sample ", :unit_price=>100}]
Any help would be appreciated.
Thannks
Try something like this
#item_name = []
#invoiceinfo.each do |invoice|
invoice_info = Invoiceinfo.find(#invoiceinfo.id)
item = {}
item[:name] = invoice_info.item.name
item[:desc] = invoice_info.desc
item[:unit_price] = invoice_info.unit_price
#item_name.push(item)
end
If you consider using ruby paradigms and best practices in ruby code, this mistake won’t happen in the future.
#item_name = #invoiceinfo.each_with_object([]) do |invoice, acc|
invoice_info = Invoiceinfo.find(#invoiceinfo.id)
acc.push(
name: invoice_info.item.name,
desc: invoice_info.desc
unit_price: invoice_info.unit_price
)
end

Array only saves the last value in ruby on rails

I have a loop which outputs information I grabbed from a website. To make the information display in an readable fashion, I insert it into an array that will be displayed on my view page. However, The array does not store all the values retrieved and instead only saves the last value appended to it. In the end I can only get the last value inserted into the array to be displayed.
My controller file...
def home
scrape()
end
private
def scrape
require 'rubygems'
require 'nokogiri'
require 'open-uri'
time = Time.new
month = I18n.t("date.abbr_month_names")[time.month]
day = time.day
#strings = []
#United States
cities = [
"sfbay", "losangeles", "athensga", "phoenix", "santabarbara", "denver",
"panamacity", "miami", "austin", "bakersfield", "keys", "newyork"
]
cities.map do |city|
#Search Terms
search_terms = ["mechanic", "car", "tech"]
search_terms.map do |term|
escaped_term = CGI.escape(term)
url = "http://#{city}.craigslist.org/search/jjj?query=#{escaped_term}&catAbb=jjj&
srchType=A"
doc = Nokogiri::HTML(open(url))
doc.css(".row").map do |row|
date = row.css(".itemdate").text
a_tag = row.css("a")[0]
text = a_tag.text
link = a_tag[:href]
#strings == []
if date = "#{month} #{day}"
#strings << "#{date} #{text} #{link}"
end
end
end
end
end
In the view home.html.erb file...
<%= raw(#strings.join('<br />')) %>
So when I go to the home page, I'm only display the last value inserted into the array. What is wrong and how do I fix it?
For one thing you create a new array for every row for every city. (But don't, actually; the assignment is a compare, ==, at the moment.)
For another you set date equal to "#{month} #{day}" instead of doing a comparison.

ruby - writing an array to a hash without overwriting

I do the following
my_hash = Hash.new
my_hash[:children] = Array.new
I then have a function that calls itself a number of time each time writing to children
my_hash[:children] = my_replicating_function(some_values)
How do I write without overwriting data that is already written ?
This is what the entire function looks like
def self.build_structure(candidates, reports_id)
structure = Array.new
candidates.each do |candidate, index|
if candidate.reports_to == reports_id
structure = candidate
structure[:children] = Array.new
structure[:children] = build_structure(candidates, candidate.candidate_id)
end
end
structure
end
Maybe this:
structure[:children] << build_structure(candidates, candidate.candidate_id)
structure[:children] << build_structure(candidates, candidate.candidate_id)

Resources