Do Threading in Rails for massive requests - ruby-on-rails-3

I am having the following code
def test
t1 = Time.now
#lat = params[:lat]
#lng = params[:lng]
#vehicleid = params[:vehicle_id]
#address = GoogleGeocoder.reverse_geocode([#lat, #lng]).full_address
speed = params[:speed]
speed ||= 0
Tracking.create(:latitude => #lat, :longitude => #lng, :address => #address, :vehicle_id => #vehicleid, :speed => speed)
uid = Vehicle.select('user_id').where('vehicle_id=?', #vehicleid)
gid = VehicleGeozone.where('vehicle_id=?', #vehicleid)
email = User.select('email').where('user_id=?', uid[0].user_id)
gzone = Geozone.where('geozone_id=?', gid[0].geozone_id)
#geofence = Geofence.where('geozone_id = ?', gzone[0].geozone_id)
if gzone[0].zonetype == 'polygon'
infence = false
res = isPointInPoly(#lat.to_f, #lng.to_f, #geofence)
else
res = isPointInCircle(#lat.to_f, #lng.to_f, #geofence[0].latitude, #geofence[0].longitude, #geofence[0].radius)
end
if res == true
AlertMailer.geofence(email[0].email).deliver
end
t2 = Time.now
render :text => '{"message":"success"}'
end
This test function is called every 5 seconds.
From t1 and t2 found that processing this function requires 7 seconds.
Is there a way to use threading so that I can move some intensive code of isPointInCircle and isPointInPoly into separate threads?

Related

releasing rooms after check out of user in a hotel reservation system using rails

In my hotel reservation system i have a rooms table which has 4 types of rooms, associated with a particular hotel. When i book the rooms e.g. if i book 2 single bedrooom and 1 double bedroom then the available rooms gets subtracted. My problem is when the user checks out i.e. if check out date >= today then i want to retrieve the booked rooms back. How can i do that.
this is my association:
class Booking < ApplicationRecord
belongs_to :hotel
belongs_to :user
validate :check_out_greater_than_check_in
end
class Hotel < ApplicationRecord
has_one :room, dependent: :destroy
has_many :bookings
belongs_to :city
validates :name, presence: true, uniqueness: true
scope :search_it, ->(s_term) { where("name LIKE ? OR city LIKE ?", "%#{s_term}%", "%#{s_term}%") }
has_attached_file :picture, styles: {large: "500x500>", medium: "300x300>", thumb: "150x150#"}
validates_attachment_content_type :picture, content_type: %r{\Aimage\/.*\z}
validates_attachment_presence :picture
end
class Room < ApplicationRecord
belongs_to :hotel
end
This is my bookings controller:
class BookingsController < ApplicationController
before_action :current_hotel, except: [:new]
after_action :alter_rooms, only: [:create]
def new
#booking = Booking.new
#single = Room.joins(:hotel).where("hotel_id = ?", params[:hotel_id]).pluck(:single_bedroom_num)
#s = #single[0].to_i
#double = Room.joins(:hotel).where("hotel_id = ?", params[:hotel_id]).pluck(:double_bedroom_num)
#d = #double[0].to_i
#suite = Room.joins(:hotel).where("hotel_id = ?", params[:hotel_id]).pluck(:suite_room_num)
#sui = #suite[0].to_i
#dormitory = Room.joins(:hotel).where("hotel_id = ?", params[:hotel_id]).pluck(:dormitory_room_num)
#dor = #dormitory[0].to_i
s = params[:single_bedroom_num]
d = params[:double_bedroom_num]
su = params[:suite_room_num]
dor = params[:dormitory_room_num]
session[:hotel_id] = params[:hotel_id]
#hotel = current_hotel
end
def index
end
def create
#hotel = current_hotel.id
#booking = #hotel.bookings.build(book_params)
if signed_in?
params[:user_id] = current_user
else
authorize
end
if #booking.save
flash.now.alert = "booked successfully!"
redirect_to root_path
else
flash.now.alert = "Oops, couldn't book."
render :new
end
end
def show
#hotel = Hotel.find(params[:hotel_id])
check_in = params[:check_in_date]
check_out = params[:check_out_date]
#single = Room.single_bedroom_num
#booking = Booking.find(params[:id])
end
private
def book_params
params.require(:booking).permit(:id, :num_of_guests, :guest_name, :check_in_date, :check_out_date, :single_bedroom_num, :double_bedroom_num, :suite_room_num, :dormitory_room_num, :hotel_name, :hotel_id, :user_id)
end
def current_hotel
#current_hotel ||= Hotel.find(session[:hotel_id])
end
def alter_rooms
#single = Room.joins(:hotel).where("hotel_id = ?", session[:hotel_id]).pluck(:single_bedroom_num)
s = #single[0].to_i
#double = Room.joins(:hotel).where("hotel_id = ?", session[:hotel_id]).pluck(:double_bedroom_num)
d = #double[0].to_i
#suite = Room.joins(:hotel).where("hotel_id = ?", session[:hotel_id]).pluck(:suite_room_num)
sui = #suite[0].to_i
#dormitory = Room.joins(:hotel).where("hotel_id = ?", session[:hotel_id]).pluck(:dormitory_room_num)
dor = #dormitory[0].to_i
#so = #booking.single_bedroom_num
s_new = #so.to_i
#duo = #booking.double_bedroom_num
d_new = #duo.to_i
#suio = #booking.suite_room_num
sui_new = #suio.to_i
#doro = #booking.dormitory_room_num
dor_new = #doro.to_i
h_id = #booking.hotel_id.to_i
s_res = (s - s_new).to_i
d_res = (d - d_new).to_i
sui_res = (sui - sui_new).to_i
dor_res = (dor - dor_new).to_i
#room = Room.find_by(hotel_id: h_id)
#room.update_attributes(single_bedroom_num: s_res, double_bedroom_num: d_res, suite_room_num: sui_new, dormitory_room_num: dor_new )
end
end

Destroy Record if Dependant record is not found

I am tring to write a script that checks to see if the corresponding record exist. if not i want to delete the record of reference.
I am new to ruby.
if Hotload.find(lead.id).exists?
leadid = Lead.find(lead.id)
leadid.destroy
end
error message:
ActiveRecord::RecordNotFound (Couldn't find Hotload with id=148):
app/controllers/users_controller.rb:64:in `block in leads'
app/controllers/users_controller.rb:47:in `leads'
UPDATE:
Here is complete Function:
def leads
load_leads = []
truck_leads = []
hotload_leads = []
#I just added another route for users/:id/leads and kept users/leads because I wasn't sure if it was used anywhere else.
#leads = Lead.where(:user_id => params[:id] || current_user.id)
#leads.each do |lead|
if lead.post_type == 'load'
load_leads.push lead.type_id
elsif lead.post_type == 'truck'
truck_leads.push lead.type_id
elsif lead.post_type == 'hotload'
hotload_leads.push lead.type_id
unless Hotload.where(:id => lead.id).exists?
lead_id = Lead.find(lead.id)
lead_id.destroy
end
end
end
#saved_loads = Load.find(load_leads, :order => "#{sort_load_column + " " + sort_direction}").paginate(:page => params[:load_leads_page], :per_page => 10)
#saved_trucks = Truck.find(truck_leads,:order => "#{sort_truck_column + " " + sort_direction}").paginate(:page => params[:truck_leads_page], :per_page => 10)
#saved_hotloads = Hotload.find(hotload_leads,:order => "#{sort_load_column + " " + sort_direction}").paginate(:page => params[:hotload_leads_page], :per_page => 10)
end
Error Now
ActiveRecord::RecordNotFound (Couldn't find all Hotloads with IDs (1590, 1479, 1478, 1468, 1476) (found 4 results, but was looking for 5)):
app/controllers/users_controller.rb:62:in `leads'
You should change the code to
if Hotload.find_by(id: lead.id).blank?
leadid = Lead.find(lead.id)
leadid.destroy
end
If you look at the documentation for find, you'll see that it will raise an error if one or more ids cannot be found.
Try using where instead.
if Hotload.where(:id => lead.id).exists?
lead_id = Lead.find(lead.id)
lead_id.destroy
end

How can I multi-edit tasks to assign each to a different user story?

In Rally, it takes a few clicks in the UI to re-parent a task. When many tasks have to be reparented it is impractical to do it one at a time. The drop down on "Multi-Edit: Task" page allows to change Name, State, Estimate, ToDo, and Owner but does not allow to change Work Product even when this column is added to a custom view on a Tasks summary page.
It is not possible to bulk-reassign tasks to a different user story in the UI. Here is a Ruby code, using Rally Ruby REST tookit
that re-assign a group of tasks based on a tag to a different story.
It is using stop_after variable just to put some guardrails around the bulk edit.
require 'rally_api'
headers = RallyAPI::CustomHttpHeader.new()
headers.name = "bulk action: set workproduct on tasks"
headers.vendor = "Nick M RallyLab"
headers.version = "1.0"
config = {:base_url => "https://rally1.rallydev.com/slm"}
config[:username] = "user#co.com"
config[:password] = "secret"
config[:workspace] = "W"
config[:project] = "P1"
config[:headers] = headers
#rally = RallyAPI::RallyRestJson.new(config)
query = RallyAPI::RallyQuery.new()
query.type = :task
query.fetch = "Name,FormattedID,Description,WorkProduct"
query.workspace = {"_ref" => "https://rally1.rallydev.com/slm/webservice/v2.0/workspace/1111" }
query.project = {"_ref" => "https://rally1.rallydev.com/slm/webservice/v2.0/project/2222" }
query.page_size = 200 #optional - default is 200
query.limit = 1000 #optional - default is 99999
query.project_scope_up = false
query.project_scope_down = true
query.order = "Name Asc"
query.query_string = "(Tags.Name = tag1)"
story = {"_ref" => "https://rally1.rallydev.com/slm/webservice/v2.0/hierarchicalrequirement/33333" }
tasks_results = #rally.find(query)
tasks = [];
stop_after = 10
count = 0
tasks_results.each do |t|
count +=1
break if count > stop_after
puts "Name: #{t["Name"]}, FormattedID: #{t["FormattedID"]}"
t.read
tasks << t
end
tasks.each do |t|
puts "acting on Name: #{t["Name"]}, FormattedID: #{t["FormattedID"]}"
field_updates = {"WorkProduct" => story}
t.update(field_updates)
end

mysql update for five tables

I have looked and looked, mostly at UPDATE with multiple tables. Once or twice I searched specificially with 5 tables. The examples mostly show only two tables.
When I run the code below I get this message:
update for memret 1: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(M.first = test, M.last = nine, M.address1 = 999 woodland, M.zip = 21122, M.emai' at line 5
From my research this happens to many. I have switched around the code numerous times. This is my latest stab at what might fly but it crashed with the same message as above.
This code is below followed by the mysql db record.
Help please!
$sql = "UPDATE membership AS M
LEFT JOIN address2 AS A2 ON M.memno1 = A2.memno2
LEFT JOIN contact AS Con ON M.memno1 = Con.memno3
LEFT JOIN workers AS W ON M.memno1 = W.memno4
LEFT JOIN comments AS Com ON M.memno1 = Com.memno5";
$sql.=" SET (M.first = $first, M.last = $last, M.address1 = $address1,";
$sql.=" M.zip = $zip, M.email = $email, M.password = $password,";
$sql.=" M.secq = $secq,M.seca = $seca,";
$sql.=" A2.address2 = $address2,";
$sql.=" Con.home = $home, Con.cell = $cell, Con.work = $work,";
$sql.=" W.webhelp = $webhelp, W.locorg = $locorg, W.candasst = $candasst,";
$sql.=" W.loccam = $loccam, W.other = $other, W.otherexp = $otherexp,";
$sql.=" Com.comment = $comment) WHERE memno1=$memno";
$result = mysql_query($sql) or die("update for memret 1: ".mysql_error());
memno1 first last address1 zip email password secq seca memno2 address2 memno3 home cell work memno4 webhelp locorg candasst loccam other otherexp memno5 comment memno6 office first last address1 address2 zip
9 test nine 999 woodland 21122 tn9#aol.com tn9999 house wreck 9 dump 9 1232224444 333556666 2223335555 9 yes yes ceo 9 test new side
This is an SQL injection. If I read the error message correctly, $address1 is "999 woodland" which will not be treated correctly by the SQL parser.
Stop substituting raw variables into query strings. (And stop using mysql_* functions, too. They're deprecated.) A prepared statement will go a long way here.
// assumes an existing PDO database connection in $conn
// requires exception-handling code (PDOException)
// requires you to check that e.g. integer fields will be updated with integers
$sql = "UPDATE membership AS M
LEFT JOIN address2 AS A2 ON M.memno1 = A2.memno2
LEFT JOIN contact AS Con ON M.memno1 = Con.memno3
LEFT JOIN workers AS W ON M.memno1 = W.memno4
LEFT JOIN comments AS Com ON M.memno1 = Com.memno5
SET (M.first = :first, M.last = :last, M.address1 = :address1,
M.zip = :zip, M.email = :email, M.password = :password,
M.secq = :secq, M.seca = :seca,
A2.address2 = :address2,
Con.home = :home, Con.cell = :cell, Con.work = :work,
W.webhelp = :webhelp, W.locorg = :locorg, W.candasst = :candasst,
W.loccam = :loccam, W.other = :other, W.otherexp = :otherexp,
Com.comment = :comment) WHERE memno1 = :memno";
$query = $conn->prepare($sql);
$params = array(":first" => $first, ":last" => $last, ":address1" => $address1,
":zip" => $zip, ":email" => $email, ":password" => $password,
":secq" => $secq, ":seca" => $seca,
":address2" => $address2,
":home" => $home, ":cell" => $cell, ":work" => $work,
":webhelp" => $webhelp, ":locorg" => $locorg,
":candasst" => $candasst,
":loccam" => $loccam, ":other" => $other,
":otherexp" => $otherexp,
":comment" => $comment, ":memno" => $memno);
$did_we_succeed = $query->execute($params);

Populating form after validation fails

I have report_controller where I have two objects, #report and #reporte, and I want to save both objects in database. When validation fails, I want to get fields populated in rendered form.
I can't use just #report = ReportMain.new(params[:report_main]) because I have two objects and just one params object.
I use exportnew action to show form, and encreate to save this form.
There is some simple way to get form populated?
ReportController:
class ReportController < ApplicationController
before_filter :authenticate_user!
before_filter :load
layout "application"
def load
#company = Company.find_by_id(current_user.company_id)
#date = Date.today
#report = ReportMain.new
#reporte = ReportE.new
end
def index
list
render("list")
end
def list
#reports = ReportMain.all
end
def exportnew
render("ennew")
end
def encreate
#report = ReportMain.new
#reporte = ReportE.new
#reportparam = params[:report_main]
#report.waste_id = params[:waste][:code]
#report.warehouse_id = Warehouse.find_by_user_id(current_user.id).id
#report.user_id = current_user.id
#report.company_id = current_user.company_id
#report.amount = #reportparam[:amount]
#report.isimport = false
#report.isfinished = false
#report.reportnumber = ReportMain.where(:company_id => current_user.company_id).count.to_i+1
if #report.save
#reporte.report_main_id = #report.id
else
#report_main = #report
render("etnew")
return
end
#reporte.vrstaotpada = params[:vrstaotpada]
#reporte.nacinpakovanja = params[:nacinpakovanja]
#reporte.ispitivanjebroj = #reportparam[:ispitivanjebroj]
#reporte.datumispitivanja = #reportparam[:datumispitivanja]
#reporte.q_pripadnost = #reportparam[:q_pripadnost]
#reporte.datumpredaje = #date
if #reporte.save
redirect_to(:action => 'show', :id => #reporte.id)
flash[:notice] = "Izveštaj je uspešno kreiran."
else
#report_main = #report
render("etnew")
end
end
def show
#report = ReportMain.find(params[:id])
#warehouse = #report.warehouse.name
end
end
View starts with (it's huge HTML):
<%= form_for(:report_main, :url => {:action => 'encreate'}) do |f| %>
Since you want your form to get populated after validation fails, I suggest make your from to submit through AJAX. There is a jQuery plugin which can help http://jquery.malsup.com/form/