CSV export customization - ruby-on-rails

I have the following piece of code which export a csv file.
- if #product.type_id == 2
= "#{l(:user)} ID , #{l(:name)} , #{l(:company)} , #{l(:item)} , #{l(:total)} , #{l(:order_time_stamp)}"
- orders = #product.orders
- orders.each do |order|
- order_users = get_user_who_order order
- order_users.each do |order_user|
- user = order_user[:user]
- products , op_total = get_products_and_total order_user[:order_products]
- company = user.company.present? ? user.company.name : ''
- products = products.join('. ')
But we have list of items which is currently rendering in a single column however we need it to be in the different columns like item1, item2, item3 and so on.

Seems a bit crazy to me to do this with haml. There is a nice CSV library in Ruby you can use for this instead.
If you still insist on doing it with haml what you are missing is printing the extra , - you need to this yourself when using haml like this. I don't see any = in your loop at all. How is it possible that you get anything printed at all? (Except the header?)

Related

Using Insert with a large multi-layered table using Lua

So I am working on a script for GTA5 and I need to transfer data over to a js script. However so I don't need to send multiple arrays to js I require a table, the template for the table should appear as below.
The issue I'm having at the moment is in the second section where I receive all vehicles and loop through each to add it to said 'vehicleTable'. I haven't been able to find the "table.insert" method used in a multilayered table
So far I've tried the following
table.insert(vehicleTable,vehicleTable[class][i][vehicleName])
This seems to store an 'object'(table)? so it does not show up when called in the latter for loop
Next,
vehicleTable = vehicleTable + vehicleTable[class][i][vehicleName]
This seemed like it was going nowhere as I either got a error or nothing happened.
Next,
table.insert(vehicleTable,class)
table.insert(vehicleTable[class],i)
table.insert(vehicleTable[class][i],vehicleName)
This one failed on the second line, I'm unsure why however it didn't even reach the next problem I saw later which would be the fact that line 3 had no way to specify the "Name" field.
Lastly the current one,
local test = {[class] = {[i]={["Name"]=vehicleName}}}
table.insert(vehicleTable,test)
It works without errors but ultimately it doesn't file it in the table instead it seems to create its own branch so object within the object.
And after about 3 hours of zero progress on this topic I turn to the stack overflow for assistance.
local vehicleTable = {
["Sports"] = {
[1] = {["Name"] = "ASS", ["Hash"] = "Asshole2"},
[2] = {["Name"] = "ASS2", ["Hash"] = "Asshole1"}
},
["Muscle"] = {
[1] = {["Name"] = "Sedi", ["Hash"] = "Sedina5"}
},
["Compacts"] = {
[1] = {["Name"] = "MuscleCar", ["Hash"] = "MCar2"}
},
["Sedan"] = {
[1] = {["Name"] = "Blowthing", ["Hash"] = "Blowthing887"}
}
}
local vehicles = GetAllVehicleModels();
for i=1, #vehicles do
local class = vehicleClasses[GetVehicleClassFromName(vehicles[i])]
local vehicleName = GetLabelText(GetDisplayNameFromVehicleModel(vehicles[i]))
print(vehicles[i].. " " .. class .. " " .. vehicleName)
local test = {[class] = {[i]={["Name"]=vehicleName}}}
table.insert(vehicleTable,test)
end
for k in pairs(vehicleTable) do
print(k)
-- for v in pairs(vehicleTable[k]) do
-- print(v .. " " .. #vehicleTable[k])
-- end
end
If there is not way to add to a library / table how would I go about sorting all this without needing to send a million (hash, name, etc...) requests to js?
Any recommendations or support would be much appreciated.
Aside the fact that you do not provide the definition of multiple functions and tables used in your code that would be necessary to provide a complete answere without making assumptions there are many misconceptions regarding very basic topics in Lua.
The most prominent is that you don't know how to use table.insert and what it can do. It will insert (append by default) a numeric field to a table. Given that you have non-numeric keys in your vehicleTable this doesn't make too much sense.
You also don't know how to use the + operator and that it does not make any sense to add a table and a string.
Most of your code seems to be the result of guess work and trial and error.
Instead of referring to the Lua manual so you know how to use table.insert and how to index tables properly you spend 3 hours trying all kinds of variations of your incorrect code.
Assuming a vehicle model is a table like {["Name"] = "MyCar", ["Hash"] = "MyCarHash"} you can add it to a vehicle class like so:
table.insert(vehicleTable["Sedan"], {["Name"] = "MyCar", ["Hash"] = "MyCarHash"})
This makes sense because vehicleTable.Sedan has numeric indices. And after that line it would contain 2 cars.
Read the manual. Then revisit your code and fix your errors.

How to update multiple instances efficiently in Rails

I have a Company model that have lending_restricted:boolean column.
The list about the restriction are collected by restricted_codes method.
And to update only necessary companies, I wrote like this:
old_codes = Company.where(lending_restricted: true).pluck(:code)
new_codes = restricted_codes
(new_codes - old_codes).each do |code|
c = Company.find_by(code: code)
c.try(:update_attributes, lending_restricted: true)
end
(old_codes - new_codes).each do |code|
c = Company.find_by(code: code)
c.try(:update_attributes, lending_restricted: false)
end
It works basically fine, but I feel it's a bit redundant to write similar function two times.
Is there better way to write a method like this?
The number of restricted_codes is about 100, and there are about 4000 companies in my Rails project.
Untested, but perhaps something like this? I've also updated your code so it's done in one query (instead of N queries).
def update_lending_restriction(codes, restriction)
Company.where(code: codes).update_all(lending_restricted: restriction)
end
old_codes = Company.where(lending_restricted: true).pluck(:code)
new_codes = restricted_codes
update_lending_restriction(new_codes - old_codes, true)
update_lending_restriction(old_codes - new_codes, false)

Ruby on Rails statement executed on an array check if subelement string is unique

I have an array objects, for this example lets call it Diff. These diffs have multiple fields that are not all the same (old_image, new_image, url, etc). new_image and old_image in this case have fields on them, most importantly a field called image_file_name.
I want to get an array of all the diffs with an unique old_image.image_file_name i.e. no diff should have an old_image with the same file name.
I believe the logic should look something like this.
unique_diffs = Array.new
#diff.build.diffs.each { |diff|
if diff.old_image.image_file_name != #diff.old_image.image_file_name
unique_diffs.push(diff)
end
}
Or something like this
#unique_diffs = #diff.build.diffs.map{|diff| diff.old_image.image_file_name}.uniq
Any help would be much appreciated.
Try something like this:
Diff = Struct.new(:old_image)
Image = Struct.new(:image_file_name)
diffs = [
Diff.new(Image.new('name1')),
Diff.new(Image.new('name2')),
Diff.new(nil),
Diff.new(Image.new('name1')),
]
uniqs = diffs.select { |diff| diff.old_image }.uniq { |diff| diff.old_image.image_file_name }
p uniqs # prints Diff with name1 and Diff with name 2
The only important line is the one that calls select and uniq.
You need to use select to leave only the diffs with the old image, and then use uniq to drop those with the duplicated image file names.
I ended up using the loop, I was hoping to make this cleaner with the uniq function but it didn't seem to work, it gave me back all the diffs instead of the ones with the unique old image filename.
#diff.build.diffs.each { |diff|
if diff.old_image.image_file_name == #diff.old_image.image_file_name
# Logic went here
end
}
Still open to improving this but for now this will have to do.

ruby on rails select a variable name using loop

There's a similar answer but it won't apply to me, but maybe will help someone: here
So, I have a loop and need to input a value into each of 20 variables, called product1, product2, ... , product20.
Im using nokogiri to change the values from a page, and manually it works:
li.content = #site.product1
li = #doc.css('li')[1]
But to avoid code repetition and also I have more cases like that one in my app im trying to make a loop, but it won't work since now.
What it need to do:
(1..20).each do |i|
li = #doc.css('li')[i]
li.content = #site.producti
end
Thanks
TRy
(0...20).each do |i|
li = #doc.css('li')[i]
li.content = #site.send("product#{i}")
end

Using index value in method

In my Rails application, in a model, I am trying to use the loop index x in the following method, and I can't figure out how to get the value:
def set_winners ## loops over 4 quarters
1.upto(4) do |x|
qtr_[x]_winner.winner = 1
qtr_[x]_winner.save
end
end
I'm going to keep searching but any help would be greatly appreciated!
edit: So I guess I can't do that! Here is the original method I was trying to refactor in full by looping four times:
def set_winners
## set all 4 quarter's winning squares
home_qtr_1 = game.home_q1_score.to_s.split('').last.to_i
away_qtr_1 = game.away_q1_score.to_s.split('').last.to_i
qtr_1_winner = squares.where(xvalue:home_qtr_1, yvalue:away_qtr_1).first
qtr_1_winner.winner = 1
qtr_1_winner.save
home_qtr_2 = game.home_q2_score.to_s.split('').last.to_i
away_qtr_2 = game.away_q2_score.to_s.split('').last.to_i
qtr_2_winner = squares.where(xvalue:home_qtr_2, yvalue:away_qtr_2).first
qtr_2_winner.winner = 1
qtr_2_winner.save
home_qtr_3 = game.home_q3_score.to_s.split('').last.to_i
away_qtr_3 = game.away_q3_score.to_s.split('').last.to_i
qtr_3_winner = squares.where(xvalue:home_qtr_3, yvalue:away_qtr_3).first
qtr_3_winner.winner = 1
qtr_3_winner.save
home_qtr_4 = game.home_q4_score.to_s.split('').last.to_i
away_qtr_4 = game.away_q4_score.to_s.split('').last.to_i
qtr_4_winner = squares.where(xvalue:home_qtr_4, yvalue:away_qtr_4).first
qtr_4_winner.winner = 1
qtr_4_winner.save
end
Is there a better way to do this if it's bad practice to dynamically change attribute names?
It looks like you are trying to do a PHP-like trick in a language that doesn't support it, and where we recommend NOT doing it because it results in code that is very difficult to debug due to the dynamically named variables.
It looks like you want to generate a variable name using:
qtr_[x]_winner
to create something like:
qtr_1_winner
Instead, consider creating an array named qtr_winner containing your objects and access the elements like:
qtr_winner[1]
or
qtr_winner[2]
etc.
You could create a hash to do a similar thing:
qtr_winner = {}
qtr_winner[1] = 5
then later access it using qtr_winner[1] and get 5 back or
qtr_winner[1].winner = 1
The determination of whether to use a hash or an array is whether you need to walk the container, or need random access. If you are always indexing into it using a value, then it's probably a wash about which is faster.
Based on your edit, you don't need dynamic variables. The only thing that changes in your loop is game.home_qN_score, so that's what the focus of your refactoring should be. Given that, here's a viable solution:
1.upto(4) do |i|
home_qtr = game.send("home_q#{i}_score)".to_s.split('').last.to_i
away_qtr = game.send("away_q#{i}_score)".to_s.split('').last.to_i
winner = squares.where(xvalue:home_qtr, yvalue:away_qtr).first
winner.winner = 1
winner.save
end
Original answer:
If qtr_1_winner, etc. are instance methods, you can use Object#send to achieve what you want:
def set_winners ## loops over 4 quarters
1.upto(4) do |x|
send("qtr_#{x}_winner").winner = 1
send("qtr_#{x}_winner").save
end
end

Resources