Update database using a loop on Ruby On Rails - ruby-on-rails

I'm trying to do a for each loop to update my database. I was using this piece of code to make the update:
def update
respond_to do |format|
#t_id = params[:t_id]
#t_order = params[:order]
#t_relation = TRelation.where('t_id' => #t_id)
#i = 0;
#t_order.each do |p|
#t_relation = TRelation.where('t_id = ? and
video_id = ?', #t_id, p[1][#i])
#i = #i + 1
#t_relation[0].t_order = #i
#t_relation[0].save
end
format.json { render :nothing => true, :status => 200, :content_type => 'text/html' }
end
end
It does not loop through; it goes through it one time and stops. I don't understand what's happening.
This is the content of params[:order]
params[:order] = {ActionController::Parameters} ActionController::Parameters (1 element)
'0' = Array (3 elements)
[0] = "7"
[1] = "5"
[2] = "3"
And if I make a #timeline_order.inspect I get this:
{"0"=>["7", "5", "3"]}
How can I loop through it? I have no idea

It iterates once because params[:order] only has one element. What you want to do is iterate on #t_order["0"], which has 3 elements.
Also, you should avoid all that logic within the respond_to. You can (should) define the variables outside of it.

Related

ruby/rails JSON to hash then changing array of the hashes then send back JSON

I have a rails app. I get JSON from 3rd party API. I would like to modify it to be able to send the proper JSON to another API. I was able to make a hash of it with JSON.parse, but I can't modify the hash properly and I don't know the preferred way to turn it back to JSON then.
In the get_own_events method I have the result array (code works properly till this). Now I'm trying to extract some attributes and returning the new formatted_result array which only contains the necessary, formatted attributes (I don't need the original result array.).
How can return/create the proper formatted_result array of hashes and then turn it back to JSON? In the code at the moment I get back the original hash not the new hash what I'm trying to create.
controller
#google = #user.socials.where(provider: "google_oauth2").first
#results_own = get_own_events(#google)
respond_to do |format|
format.html
format.json { render json: #results_own }
end
method
def get_own_events(social_object)
client = init_google_api_calendar_client(social_object)
old_token = client.authorization.access_token
service = client.discovered_api('calendar', 'v3')
result_raw = client.execute(
:api_method => service.events.list,
:parameters => { 'calendarId' => social_object.email,
'timeMin' => "2015-12-27T00:00:00+00:00",
'timeMax' => "2016-01-30T00:00:00+00:00" },
:headers => {'Content-Type' => 'application/json'})
result = JSON.parse(result_raw.body)['items']
formatted_result = result.each do |event|
title = event['summary']
if event['start']['dateTime']
start_time = event['start']['dateTime'].to_datetime.rfc822
end
if event['end']['dateTime']
end_time = event['end']['dateTime'].to_datetime.rfc822
end
if event['start']['date'] && event['end']['date'] && (event['start']['date'] != event['end']['date'])
all_day = true
start_allday_date = event['start']['date'].to_datetime.rfc822
end_allday_date = event['end']['date'].to_datetime.rfc822
end
formatted_event = {}
formatted_event['title'] = title
formatted_event['start'] = start_time || start_allday_date
formatted_event['end'] = end_time || end_allday_date
formatted_event['allDay'] = all_day || false
return formatted_event
end
return formatted_result
end
Changing .each to a .map may solve you're problem and go ahead and remove the return formatted_result at the end as you don't need it in Ruby because it's the last thing in your method and so
change this
formatted_result = result.each do |event|
...
return formatted_event
end
return formatted_result
to this
result.map do |event|
...
formatted_event
end
If you are trying to populate a new collection, use map instead of each. So,formatted_result = result.each do |event| should be formatted_result = result.map do |event|.
formatted_result = result.map do |event|
title = event['summary']
if event['start']['dateTime']
start_time = event['start']['dateTime'].to_datetime.rfc822
end
if event['end']['dateTime']
end_time = event['end']['dateTime'].to_datetime.rfc822
end
if event['start']['date'] && event['end']['date'] && (event['start']['date'] != event['end']['date'])
all_day = true
start_allday_date = event['start']['date'].to_datetime.rfc822
end_allday_date = event['end']['date'].to_datetime.rfc822
end
formatted_event = {}
formatted_event['title'] = title
formatted_event['start'] = start_time || start_allday_date
formatted_event['end'] = end_time || end_allday_date
formatted_event['allDay'] = all_day || false
formatted_event
end

Ruby: compare hash to hash value trouble

I have such part of "ghost look like" code (but it so must be, as db is huge and have many tables):
def search_group
#search_trees = SearchTree.all
#designation = Designation.find(:all, :conditions => { :DES_ID => #search_trees.map(&:STR_DES_ID)})
#text = DesText.find(:all, :conditions => { :TEX_ID => #designation.map(&:DES_TEX_ID)})
#search_result = #text.find_all{|item| item.TEX_TEXT.include?(params[:search_group_text])}
#designation_back = #designation.find_all{|item| item.DES_TEX_ID == #search_result.TEX_ID}
#search_trees_back = #search_trees.find_all{|item| item.STR_DES_ID == #designation_back.DES_ID}
respond_to do |format|
format.html
end
end
I try to compare
#designation_back = #designation.find_all{|item| item.DES_TEX_ID == #search_result.TEX_ID}
but i get errors, something bad...undefined method `TEX_ID'. As i think, it's via i compare hash and hash in bad way... How can i do this?
#search_result = #text.find_all{|item| item.TEX_TEXT.include?(params[:search_group_text])}
#designation_back = #designation.find_all{|item| item.DES_TEX_ID == #search_result.TEX_ID}
it's because #search_result is an array and not an object where you can call that method on.
#search_results is an array. If you know it is returning just one result, you can do #search_results[0].Tex_Id, otherwise have to loop through for each value of #search_results.
try 'pry' gem to debug what results you are getting from each assignment.

Ruby on Rails - Import CSV file

I'm following this tutorial CSV-FILE-EXPORT-IMPORT-RAILS but something im doing wrong, because i got an silly error when i'm trying to create my object uninitialized constant CuentaContablesController::False. I can read the file without problem, but this error is giving me an headache! Any help will be appreciated!
The method for import in my controller(cuenta_contable_controller.rb) looks like this;
class CuentaContablesController < ApplicationController
....
def upload(params)
logger.info "**File loaded***"
infile = params[:file].read
n, errs = 0, []
#archivo = []
SV.parse(infile) do |row|
n += 1
# SKIP: header i.e. first row OR blank row
next if n == 1 or row.join.blank?
cuenta_contable = CuentaContable.build_from_csv(row)
if cuenta_contable.valid?
cuenta_contable.save
#archivo << row
else
errs << row
end
end
logger.info errs
flash[:success] = "Las cuentas contables fueron cargadas."
respond_to do |format|
format.html # index.html.erb
format.json { render :json => #archivo }
end
end
And my model(cuenta_contable.rb) like this
class CuentaContable < ActiveRecord::Base
....
def self.build_from_csv(row)
ultimo_nivel = (row[5].downcase=="si") ? (True):(False)
#cuenta = find_or_initialize_by_cuenta("#{row[0]}-#{row[1]}-#{row[2]}")
# Buscas el archivo existing customer from email or create new
cuenta = CuentaContable.new(:cuenta => "#{row[0]}-#{row[1]}-#{row[2]}",
:descripcion => "#{row[3].titleize}",
:categoria_cuenta => "#{row[4].titleize}",
:ultimo_nivel=> ultimo_nivel)
return cuenta
end
You're using True instead of true (likewise for false).
But neither are necessary; the ternary is superfluous and over-parenthesized:
# Ick!
ultimo_nivel = (row[5].downcase=="si") ? (True):(False)
# Pretty!
ultimo_nivel = row[5].downcase == "si"
You might even use a helper to turn row 5 into a boolean and remove it from the mainline code.

Slice/Map Ordered Hash

I am writing a "Punch Clock" application for my office.. I am working on the controller for the "TIme Card" view which should list a users punches for a given week, and total DAILY then add the TOTAL for the week. I have figured out how to get the time diff between all of the punches with slice/map, my issue is that when I try to do this on the ordered hash (grouped by days) I get undefined method `created_at' for #, I know I must be missing some syntax somewhere, your help is greatly appreciated...
Here is my controller...
Note that if i call #in_out_lenghts on #punches, this works and gives me the total for the week, but #punches_days gives me an error, therefore I can not keep a running tally....
def mytimecard
#week = params[:week].to_s
if #week == "lastweek"
#punches = Punch.lastweek.where("user_id = ?", params[:user])
else
#punches = Punch.thisweek.where("user_id = ?", params[:user])
end
#punches_days = #punches.group_by { |t| t.created_at.beginning_of_day}
if #punches.count%2 == 0
#in_out_lengths = #punches_days.each_slice(2).map { |a|(a[1].created_at).round(15.minutes) - (a[0].created_at).round(15.minutes) }
#total = ((#in_out_lengths.inject(:+))/60/60)
else
#total = "Can Not Calculate, Odd Number of Punches"
end
respond_to do |format|
format.html # timecard.html.erb
format.json { render :json => #punches }
end
end
group_by will return a hash of days and punches.
{ :day_1 => [ :punch1, :punch2], :day_2 => [ :punch3, :punch4, :punch5 ] }
doing an each_slice and a map will result in some sort of array, but probably not what you meant.
You may have meant to count the number of punches and call something like this
Punch.lastweek.where("user_id = ?", params[:user]).group('date(created_at)')
This would have resulted in the date => punches_count format, at least with mysql.

Rails: How to manipulate find(params[])

I am trying to use Object.find(params[]) to only return objects with :stage_id = integer
Here is my controller code
def show
#lesson = Lesson.find(params[:id])
#stage1 = #lesson.units(params[:stage_id] == 1)
#stage2 = #lesson.units(params[:stage_id] == 2)
Each lesson has many units, each unit has either a stage_id = 1 or stage_id = 2, I want #stage1 to become an array with units that only have a stage_id value of 1. The same goes for stage2.
How can I properly use params to return only units that have the indicated table values?
def show
#lesson = Lesson.find(params[:id])
#stage1 = #lesson.units.first(:conditions => { :stage_id => 1 })
#stage2 = #lesson.units.first(:conditions => { :stage_id => 2 })
end
Ref find
#stage1 = Unit.find(:all, :conditions => ["stage_id=? AND lession_id=?" 1, params[:id]])
#stage2 = Unit.find(:all, :conditions => ["stage_id=? AND lession_id=?" 2, params[:id]])
If Units are "always' going to be structured with Stages, one thing you could do to DRY up your code is to have a Stage model. That allows flexibility to add more stages in the future without breaking code. Assuming that relationship is properly established and data is good, you could do something like the following.
controller code
#lesson = Lesson.find(params[:id])
view code (haml)
- for stage in #lesson.stages
= stage.name
- for unit in stage.units
= unit.name

Resources