Rails - Simple Loop Not Working - ruby-on-rails

In my controller I am trying to do a bulk insert into a table, in my first attempt it works but the names somehow get mangled as the following: (loop runs 24 times which is what I want)
test-port-name-0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-21
test-port-name-0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20
test-port-name-0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19
test-port-name-0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18
test-port-name-0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17
test-port-name-0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16
test-port-name-0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15
test-port-name-0-1-2-3-4-5-6-7-8-9-10-11-12-13-14
test-port-name-0-1-2-3-4-5-6-7-8-9-10-11-12-13
test-port-name-0-1-2-3-4-5-6-7-8-9-10-11-12
test-port-name-0-1-2-3-4-5-6-7-8-9-10-11
test-port-name-0-1-2-3-4-5-6-7-8-9-10
test-port-name-0-1-2-3-4-5-6-7-8-9
test-port-name-0-1-2-3-4-5-6-7-8
test-port-name-0-1-2-3-4-5-6
test-port-name-0-1-2-3-4-5-6-7
test-port-name-0-1-2-3-4-5
test-port-name-0-1-2-3-4
test-port-name-0-1-2
test-port-name-0-1-2-3
test-port-name-0
test-port-name-0-1
test-port-name-0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-21-22
test-port-name-0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-21-22-23
instead of test-port-name-0 .... test-port-name-23
def bulk_port_import
if request.post?
#attempt create
count = 0
for i in 1..session[:no_ports]
params[:dp][:name] = params[:dp][:name] + '-' + count.to_s
#dp = DevicePort.create params[:dp]
count = count + 1
end
end
#success = "Saved." if #dp.valid?
#error = ""
#dp.errors.each_full {|e| #error += e + ", "}
redirect_to '/device/update/' + params[:dp][:device_id]
end
Different attempt:
def bulk_port_import
if request.post?
#attempt create
i = 0
while i < session[:no_ports] do
params[:dp][:name] = params[:dp][:name] + '-' + i.to_s
#dp = DevicePort.create params[:dp]
i++
end
end
session.delete(:no_ports)
#success = "Saved." if #dp.valid?
#error = ""
#dp.errors.each_full {|e| #error += e + ", "}
redirect_to '/device/update/' + params[:dp][:device_id]
end
but with this I get syntax error, unexpected kEND and I can't see what I'm doing wrong in either case, it's probably something stupid, again.

Its because you are changing params[:dp][:name] in the loop
def bulk_port_import
if request.post?
#attempt create
count = 0
for i in 1..session[:no_ports]
dp_name = params[:dp][:name] + '-' + count.to_s
#dp = DevicePort.create(params[:dp].merge(:name => dp_name))
count = count + 1
end
end
#success = "Saved." if #dp.valid?
#error = ""
#dp.errors.each_full {|e| #error += e + ", "}
redirect_to '/device/update/' + params[:dp][:device_id]
end

Related

RoR: Method to return a statement in a json format?

I'm looking for a method that will return this statement in a JSON format.
def statement
total = 0
bonus points = 0
result = 'Car rental for #{#name.to_s}\n'
for r in #rentals
this_amount = 0
case r.car.style
when Car::SUV
this_amount += r.days_rented * 30
when Car::HATCHBACK
this_amount += 15
if r.days_rented > 3
this_amount += (r.days_rented - 3) * 15
end
when Car::SALOON
this_amount += 20
if r.days_rented > 2
this_amount += (r.days_rented - 2) * 15
end
else
end
if this_amount < 0
bonus_points -= 10
end
bonus_points = bonus_points + 1
if r.car.style == Car::SUV && r.days_rented > 1
bonus_points = bonus_points + 1
end
result += r.car.title.to_s + "," + this_amount.to_s + "\n"
total += this_amount
end
result += "Amount owed is " + "#{total.to_s}" + "\n"
result +="Earned bonus points: " + bonus_points.to_s
result
end
What method would I need to add to my class to return this statement in a JSON format? Thank you.
Simplest way to do that
return {:result => result}
at the end of your method.
But if you are using controller to show data to user, I would prefer using .to_json in my controller method

How to have an ouput without symbols and quotations etc. in Ruby

In this particular code when the input[0] = "status", I want the output to remove the symbols "" [] and , but I can't seem to find the solution, I've tried using each but I think what I'm doing is wrong, and I'm new to Ruby please help. Thanks!
class Main
puts "Welcome to the automated Parking Lot"
start = true
parking_lot = []
allocated_slot = 0
slot_number = 0
plate_number = ""
color = ""
x = ""
while (start == true) do
parking = Array.new
input = gets.split(' ')
case input[0]
when input[0] = "create_parking_lot"
parking_lot.clear
allocated_slot = input[1]
puts "Created a parking lot with #{allocated_slot} slots."
when input[0] = "park"
plate_number = input[1]
color = input[2]
if parking_lot.length < allocated_slot.to_i
slot_number = slot_number + 1
parking = [slot_number, input[1], input[2]]
parking_lot.push(parking)
parking_lot.sort!
puts "Allocated slot number: #{slot_number}"
else
puts "Sorry, parking lot is full"
end
when input[0] = "leave"
slot_number = input[1].to_i
puts "Slot number #{slot_number} is now free."
slot_number = slot_number - 1
parking_lot.delete_at(slot_number)
parking_lot[slot_number]
#puts parking_lot
when input[0] = "quit"
break
when input[0] = "status"
if parking_lot.count == 0
puts "No cars are parked."
else
puts "Slot No. Registration No. Color"
parking.sort!
i = 0
y = ""
while i < allocated_slot.to_i do
x = parking_lot[i].to_s
y = x.split(' ')
puts "#{y[0]} #{y[1]} #{y[2]}" #
#y.each { |a| print a, " " }
i = i+1
end
end
when input[0] = "registration_numbers_for_cars_with_color"
puts "registration number for cars"
when input[0] = "slot_numbers_for_cars_with_color"
puts "slot number for cars with color"
when input[0] = "slot_number_for_registration_number"
puts "slot number for registration number"
when input[0] = "check"
puts parking_lot
else
puts "Command Error"
end
end
and the output goes like this:
[1, "HA-312424242", "Green"]
If you have an array being outputted that looks like this:
[1, "HA-312424242", "Green"]
Then you can call the join method on it like this:
[1, "HA-312424242", "Green"].join(' ')
and it will produce:
"1 HA-312424242 Green"

Error with virtual tree program ruby

I have just started learning ruby and have made this program following a tutorial.
I keep getting an error when trying to run and can't find an answer.
The program is suppose to be able to pick fruit, count the fruit, give the height and grow.
C:\Sites\testfolder>ruby orangetree.rb
orangetree.rb:2:in `initialize': wrong number of arguments (1 for 0) (ArgumentEr
ror)
from orangetree.rb:51:in `new'
from orangetree.rb:51:in `<class:OrangeTree>'
from orangetree.rb:1:in `<main>'
C:\Sites\testfolder>
Here is the program
class OrangeTree
def initialize
#age = 0
#tall = 0
#fruit = 0
puts 'You have planted a new tree!'
def height
puts 'The tree is ' + #tall.to_s + 'foot tall.'
end
def pickAFruit
if #fruit <= 1
puts 'There is not enough fruit to pick this year.'
else
puts 'You pick an orange from the tree.'
#fruit = #fruit - 1
end
end
def countOranges
puts 'The tree has ' + #fruit.to_s + 'pieces of fruit'
end
def oneYearPasses
#age = #age + 1
#tall = #tall + 3
#fruit = 0
if dead?
puts 'The Orange Tree Dies'
exit
end
if #age > 2
#fruit = #age*10
else
#fruit = 0
end
end
private
def dead?
#age > 5
end
end
tree = OrangeTree.new 'tree'
command = ''
while command != 'exit'
puts 'please enter a command for the virual tree'
command = gets.chomp
if command == 'tree height'
tree.height
elsif command == 'pick fruit'
tree.pickAFruit
elsif command == 'wait'
tree.oneYearPasses
elsif command == 'count fruit'
tree.countOranges
elsif command == 'exit'
exit
else
puts 'Cant understand your command, try again'
end
end
end
Can anybody help?
You have some syntax errors. I have fixed them below. The syntax errors were:
You had an extra end on the last line (for closing the class declaration)
You were passing an argument to OrangeTree.new ("tree") that was unexpected. This is what the wrong number of arguments (1 for 0) error message in your question is referring to.
You were missing an end to close your initialize method declaration (after the puts 'You have planted a new tree!' line)
I have also fixed the indentation, which makes the code more readable and much easier to spot syntax errors like this.
class OrangeTree
def initialize
#age = 0
#tall = 0
#fruit = 0
puts 'You have planted a new tree!'
end
def height
puts 'The tree is ' + #tall.to_s + 'foot tall.'
end
def pickAFruit
if #fruit <= 1
puts 'There is not enough fruit to pick this year.'
else
puts 'You pick an orange from the tree.'
#fruit = #fruit - 1
end
end
def countOranges
puts 'The tree has ' + #fruit.to_s + 'pieces of fruit'
end
def oneYearPasses
#age = #age + 1
#tall = #tall + 3
#fruit = 0
if dead?
puts 'The Orange Tree Dies'
exit
end
if #age > 2
#fruit = #age*10
else
#fruit = 0
end
end
private
def dead?
#age > 5
end
end
tree = OrangeTree.new
command = ''
while command != 'exit'
puts 'please enter a command for the virual tree'
command = gets.chomp
if command == 'tree height'
tree.height
elsif command == 'pick fruit'
tree.pickAFruit
elsif command == 'wait'
tree.oneYearPasses
elsif command == 'count fruit'
tree.countOranges
elsif command == 'exit'
exit
else
puts 'Cant understand your command, try again'
end
end

unexpected keyword_end, expecting end-of-input

I get a error: syntax error, unexpected keyword_end, expecting end-of-input. Normally i woudnt ask such questions but im simply cannot the error! Here is my full model code:
The error appears in the method add_gelesen line 48: end Thanks to the community!
class Message < ActiveRecord::Base
attr_accessor :current_user, :current_department
before_save :set_sender, :add_gelesen
def set_sender
self.sender_username = #current_user.username
self.sender_model = #current_user.class.to_s
self.sender_id = #current_user.id
if (recipient_username != #current_department.username) && (recipient_model == 'Department')
self.privat = 0
if Object.const_get(recipient_model).find(recipient_id).has_kontakt?(#current_department.id) == false
Object.const_get(recipient_model).find(recipient_id).kontakt(#current_department.id)
end
end
end
def add_gelesen
if self.privat == true
if recipient_username == #current_department.username
f = JSON.parse(#current_department.gelesen)
#current_department.employees.each.do |c|
w = f["#{c.username}"].nil? ? 0 : f["#{c.username}"]
f["#{c.username}"] = w + 1
end
#current_department.update_column(:gelesen, f.to_json)
else
f = JSON.parse(#current_user.gelesen)
w = f[self.recipient_username].nil? ? 0 : f[self.recipient_username]
f[self.recipient_username] = w + 1
#current_user.update_column(:gelesen, f.to_json)
end
else
u = Object.const_get(self.recipient_model).find(self.recipient_id)
f = JSON.parse(u.gelesen)
#current_department.employees.each.do |c|
w = f["#{c.username}"].nil? ? 0 : f["#{c.username}"]
f["#{c.username}"] = w + 1
end
Department.find(self.recipient_id).employees.each.do |g|
w = f["#{g.username}"].nil? ? 0 : f["#{g.username}"]
f["#{g.username}"] = w + 1
end
u.update_column(:gelesen, f.to_json)
end
end
end
The lines w/ do in them should not have the .
#current_department.employees.each.do |c|
should be
#current_department.employees.each do |c|
do is the keyword for beginning a block, not a method on each

archiloque-rest-client: change content-type to multipart/related when posing a file

Using
http://github.com/archiloque/rest-client
When posting a file using this line, the content type is set as
Content-Type: multipart/form-data; boundary=301405
in the header, by default.
RestClient.post '/data', :myfile => File.new("/path/to/image.jpg", 'rb')
I tried this and it still sets the header multipart/form-data.
RestClient.post '/data', :myfile => File.new("/path/to/image.jpg", 'rb'), :content_type => 'multipart/related'
Has anybody tried setting multipart/related?
Or you can use rather new-ish multipart_body gem:
http://steve.dynedge.co.uk/2010/09/19/multipart-body-a-gem-for-working-with-multipart-data/
Ok. I could not find a better alternative, so ended up with the following app.
It is based on this code here.
http://stanislavvitvitskiy.blogspot.com/2008/12/multipart-post-in-ruby.html
Usage:
files = { File.new("myfile1","rb"), File.new("myfile2","rb")}
mpost = Mutipart("main", "<my xml main part content which refers to file names>",files )
mpost.post("our_url","post")
Note: This code is not production ready. It is just functional.
---------------- multipart.rb -------------
require 'net/http'
require 'uri'
require 'pp'
require 'mime/types'
class Multipart
def initialize( main_part_id, main_part_content, file_names )
#file_names = file_names
#main_part_id = main_part_id
#main_part_content = main_part_content
end
def post( to_url, method = :post )
boundary = "###-------#{Time.new}-----####"
parts = []
streams = []
# write main part first
parts << StringPart.new( "--" + boundary + "\r\n")
parts << StringPart.new("Content-Disposition: name=\"#{#main_part_id}\";\"\r\n" +
"Content-ID: #{#main_part_id}\r\n\r\n"+
"Content-Type: application/xml\r\n\r\n" +
#main_part_content + "\r\n\r\n")
parts << StringPart.new( "\r\n--" + boundary + "\r\n")
#file_names.each do |param_name, filestream|
raise 'mutlipartsend: empty file object' if filestream.blank?
filename= filestream.respond_to?(:original_path) ? filestream.original_path : filestream.path
ctype = filestream.respond_to?(:content_type) ? filestream.content_type: nil
fsize = filestream.respond_to?(:lstat) ? filestream.lstat.size : filestream.size
if !ctype
begin
pos = filename.rindex('/') # if filename is a path
fname = filename[pos + 1, filename.length - pos]
mm = MIME::Types.type_for(fname)
ctype = mm.first.content_type if !mm.blank?
rescue Exception => e
p e.message
end
end
if !ctype
ctype= 'application/binary'
p "mutlipartsend: failed to determine contenttype for #{filename}. using application/binary"
end
parts << StringPart.new("Content-Disposition: name=\"" + param_name.to_s + "\"; filename=\"" + filename + "\"\r\n" +
"Content-Type: #{ctype}\r\n\r\n")
#"Content-Type: application/binary\r\n\r\n")
begin
stream = File.open(filestream.path,"rb")
streams << stream
parts << StreamPart.new(stream, fsize)
parts << StringPart.new( "\r\n--" + boundary + "\r\n" )
rescue Exception => e
p 'failed to load filestream '+ filestream.path
p e.message
raise 'failed to load filestream ' + e.message
end
end
post_stream = MultipartStream.new( parts )
url = URI.parse( to_url )
req = method == :post ? Net::HTTP::Post.new(url.path) : Net::HTTP::Put.new(url.path)
req.content_length = post_stream.size
req.content_type = 'multipart/mixed; boundary=' + boundary
req["myheader1"] = 'header1'
req["myheader2"] = 'header2'
req.body_stream = post_stream
res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }
streams.each do |stream|
stream.close();
end
res
end
end
class StreamPart
def initialize( stream, size )
#stream, #size = stream, size
end
def size
#size
end
def read( offset, how_much )
#stream.read( how_much )
end
end
class StringPart
def initialize ( str )
#str = str
end
def size
#str.length
end
def read ( offset, how_much )
#str[offset, how_much]
end
end
class MultipartStream
def initialize( parts )
#parts = parts
#part_no = 0;
#part_offset = 0;
end
def size
total = 0
#parts.each do |part|
total += part.size
end
total
end
def read ( how_much )
if #part_no >= #parts.size
return nil;
end
how_much_current_part = #parts[#part_no].size - #part_offset
how_much_current_part = if how_much_current_part > how_much
how_much
else
how_much_current_part
end
how_much_next_part = how_much - how_much_current_part
current_part = #parts[#part_no].read(#part_offset, how_much_current_part )
if how_much_next_part > 0
#part_no += 1
#part_changed=true
#part_offset = 0
next_part = read( how_much_next_part )
current_part + if next_part
next_part
else
''
end
else
#part_offset += how_much_current_part
current_part
end
end
end

Resources