How to use ruby .map to add quotes to array elements - sql

See my example below where I put 'something' I'm just confused on what to map:
array_ids = ['1','2']
array = array_ids.map(something).join(',')
So when I do:
order_sql = "FIELD(ID,#{array})"
I get this:
order_sql = "FIELD(ID,'1','2')"

You can do something like:
array_ids = ['1','2']
array = array_ids.map { |id| "'#{id}'" }.join(',')
p array
# => "'1','2'"
order_sql = "FIELD(ID,#{array})"
p order_sql
# => "FIELD(ID,'1','2')"
Hope that helps!

Related

Erlang ets:select sublist

Is there a way in Erlang to create a select query on ets table, which will get all the elements that contains the searched text?
ets:select(Table,
[{ %% Match spec for select query
{'_', #movie_data{genre = "Drama" ++ '_' , _ = '_'}}, % Match pattern
[], % Guard
['$_'] % Result
}]) ;
This code gives me only the data that started (=prefix) with the required text (text = "Drama"), but the problem is I need also the the results that contain the data, like this example:
#movie_data{genre = "Action, Drama" }
I tried to change the guard to something like that -
{'_', #movie_data{genre = '$1', _='_'}}, [string:str('$1', "Drama") > 0] ...
But the problem is that it isn't a qualified guard expression.
Thanks for the help!!
It's not possible. You need to design your data structure to be searchable by the guard expressions, for example:
-record(movie_data, {genre, name}).
-record(genre, {comedy, drama, action}).
example() ->
Table = ets:new('test', [{keypos,2}]),
ets:insert(Table, #movie_data{name = "Bean",
genre = #genre{comedy = true}}),
ets:insert(Table, #movie_data{name = "Magnolia",
genre = #genre{drama = true}}),
ets:insert(Table, #movie_data{name = "Fight Club",
genre = #genre{drama = true, action = true}}),
ets:select(Table,
[{#movie_data{genre = #genre{drama = true, _ = '_'}, _ = '_'},
[],
['$_']
}]).

How to remove "id" from json string in ruby on rails?

I have got data without "id" field from database. But when I parse the data to json string and show it on screen, I saw an "id" field on json string. How to remove this "id" field?
Here is my code:
-report_logic.rb
def fetch_data ()
#datalist=WorkEarlyOverTime
#datalist = #datalist.joins("INNER JOIN `works` ON `work_early_over_times`.`work_id` = `works`.`id`")
#datalist = #datalist.select('`work_early_over_times`.work_id AS 1次協力会社名','`work_early_over_times`.working_temp_person AS 職種名','`work_early_over_times`.working_temp_hour AS 作業場所','`work_early_over_times`.at_time_overtime_start AS 作業内容','`works`.`contents`')
#datalist = #datalist.where(work_id: $work_id)
return #datalist
end
- report_controller.rb
def work_late
report_logic = ReportLogic.new(params)
#work_late = report_logic.fetch_data()
render action: :work_late
end
- work_late.json.jbuilder
json.一覧 #work_late
When I show the string I expected the output is:
{"一覧":[
{"1次協力会社名":1,
"職種名":"0",
"作業場所":"0.00 ",
"作業内容":"2000-01-01T19:00:00.000+00:00",
"contents":"作業内容1"}
]}
but the actual output is:
{"一覧":[
{"id":null,
"1次協力会社名":1,
"職種名":"0",
"作業場所":"0.00 ",
"作業内容":"2000-01-01T19:00:00.000+00:00",
"contents":"作業内容1"}
]}
As your desired output is a JSON, you could try .as_json by excepting the id field as follows:
#datalist.select('`work_early_over_times`.work_id AS 1次協力会社名','`work_early_over_times`.working_temp_person AS 職種名','`work_early_over_times`.working_temp_hour AS 作業場所','`work_early_over_times`.at_time_overtime_start AS 作業内容','`works`.`contents`').as_json(:except => :id)
Your detailed fetch_data function will be like this:
def fetch_data ()
#datalist=WorkEarlyOverTime
#datalist = #datalist.joins("INNER JOIN `works` ON `work_early_over_times`.`work_id` = `works`.`id`")
#datalist = #datalist.select('`work_early_over_times`.work_id AS 1次協力会社名','`work_early_over_times`.working_temp_person AS 職種名','`work_early_over_times`.working_temp_hour AS 作業場所','`work_early_over_times`.at_time_overtime_start AS 作業内容','`works`.`contents`').as_json(:except => :id)
#datalist = #datalist.where(work_id: $work_id)
return #datalist
end
If id is always null then just ignore all nils:
json.ignore_nil!
json.一覧 #work_late
If that's not the case then you have to filter out the id before serializing it. One way would be:
json.一覧 #work_late.serializable_hash.except("id")

linq results for display in view - How to apply grouping

How can I group the results of this query by wl.WishlistID?
var projected = (from wl in context.Wishlists.Where(x => x.UserId == 6013)
from wli in wl.WishlistItems
select new wishListProjection
{
wlId = wl.WishlistID,
wlUserId = (int)wl.UserId,
wlDesc = wl.description,
wlTitle = wl.Title,
wliWishlistItemID = wli.WishlistItemID,
wliQtyWanted = (int)wli.QtyWanted,
wliPriceWhenAdded = wli.PriceWhenAdded,
wliDateAdded = (DateTime)wli.DateAdded,
wliQtyBought = (int)wli.QtyBought,
}).ToList();
This returns the results I want, but I want to be able to iterate over them in the view without repeating the parent-level Wishlist object.
I've tried adding the line:
group wl by wl.WishlistID into g
But I don't seem to be able to access any properties by using g.[propertyname]
This grouping achieves more or less what I want, but I want to convert the results into a new or anonymous type, rather than return the entire object.
var results = context.WishlistItems.GroupBy(x => x.Wishlist).
Select(group => new { wl = group.Key, items = group.ToList() }).ToList();
You cannot access the properties of g because when you do the grouping:
group wl by wl.WishlistID into g
g is of type IGrouping<typeof(wl.WishlistID),typeof(wl)>, which is essentially a collection of all wl's with the same key wl.WishlistID. In other words, you cannot access the properties of g because g is not a single entity, it is a collection of those entities.
For your second grouping you said you would like to create an anonymous type instead of the entire object. You can do this by doing the selection first and then grouping:
var results = context.WishlistItems
.Select(x => new { })
.GroupBy(x => x.PropertyOfProjection)
.Select(group => new { wl = group.Key, items = group.ToList() }).ToList();
Or, using a nested sub query in your first example:
var projected = (from x in
(from wl in context.Wishlists.Where(x => x.UserId == 6013)
from wli in wl.WishlistItems
select new wishListProjection
{
wlId = wl.WishlistID,
wlUserId = (int)wl.UserId,
wlDesc = wl.description,
wlTitle = wl.Title,
wliWishlistItemID = wli.WishlistItemID,
wliQtyWanted = (int)wli.QtyWanted,
wliPriceWhenAdded = wli.PriceWhenAdded,
wliDateAdded = (DateTime)wli.DateAdded,
wliQtyBought = (int)wli.QtyBought,
})
group x by w.wlId into g).ToList();
I'm not sure what you mean by iterate without repeating the parent-level Wishlist object because whenever you create a grouping in Linq you will still have to have a nested foreach like:
foreach (var x in grouping)
{
x.Key;
foreach (var y in x)
{
y.Property;
}
}

How do I combine AND and OR using Sequel?

I want to generate a SQL query like the following using Ruby's Sequel:
SELECT * FROM Objects WHERE (color = "red" AND shape = "triangle") OR
(color = "blue" AND shape = "square") OR
(color = "green" AND shape = "circle")
I want to build this query programmatically from a list of conditions, so that I can do something like this:
conditions = [[[:color, "red"], [:shape, "triangle"]],
[[:color, "blue"], [:shape, "square"]],
[[:color, "green"], [:shape, "circle"]]]
DB[:Users].where(conditions.sql_or)
It doesn't have to follow that exact form, but I want to be able to build the conditions programmatically, so it's not sufficient to be able to construct this query by hand.
Try this:
conditions = [
{:color => "red", :shape => "triangle"},
{:color => "blue", :shape => "square"},
{:color => "green", :shape => "circle"}
]
head, *tail = *conditions
tail.inject(DB[:Users].filter(head)){|mem,obj| mem.or(obj) }
I get:
=> #<Sequel::Postgres::Dataset: "SELECT * FROM \"Users\" WHERE (((\"color\" = 'red') AND (\"shape\" = 'triangle')) OR ((\"color\" = 'blue') AND (\"shape\" = 'square')) OR ((\"color\" = 'green') AND (\"shape\" = 'circle')))">
I think this will return an equivalent result, using a different SQL query:
DB[:Objects].where('(color, shape) in ?', conditions.sql_value_list).sql
=> "SELECT * FROM `Objects` WHERE ((color, shape) in (('red', 'triangle'), ('blue', 'square'), ('green', 'circle')))"
sql_value_list is documented in http://sequel.rubyforge.org/rdoc/classes/Array.html
Otherwise use:
objects = DB[:Objects].where(conditions[0])
conditions[1 .. -1].each { |c| objects = objects.or(c) }
Which results in:
SELECT * FROM `Objects` WHERE (((`color` = 'red') AND (`shape` = 'triangle')) OR ((`color` = 'blue') AND (`shape` = 'square')) OR ((`color` = 'green') AND (`shape` = 'circle')))
I was looking at Iain's answer, and it's basically the same as my second one, only more succinct; I like its elegance.

Avoid repeating an expression in a LINQ to Entities query

I have the following query:
val = val.Select(item => new SimpleBill { CTime = item.CTime, Description = item.Description, ID = item.ID,
IDAccount = item.IDAccount, OrderNumber = item.OrderNumber, PSM = item.PSM, Sum = item.Sum,
Type = (BillType)item.Type,
ByteStatus = ((Bill)item).Payments.OrderByDescending(payment => payment.ID).FirstOrDefault().Status,
LastPaymentDate = ((Bill)item).Payments.OrderByDescending(payment => payment.ID).FirstOrDefault().CTime,
LastPaymentSum = ((Bill)item).Payments.OrderByDescending(payment => payment.ID).FirstOrDefault().Sum });
}
Is it possible to avoid repeating the ((Bill)item).Payments.OrderByDescending(payment => payment.ID).FirstOrDefault() part 3 times? I tried turning it into a method and into a delegate - the code compiled in both cases, but produced an exception at runtime.
You can use the let contstruct as follows:
val = from item in val
let lastPayment = ((Bill)item).Payments
.OrderByDescending(payment => payment.ID)
.FirstOrDefault()
select new SimpleBill
{
lastPayment.CTime,
//Rest of fields
}
However, as you may noticed this uses the LINQ Query syntax vs. Method syntax. IIRC let is only available in the former.