How to check included ID or not? - ruby

I have ActiveRecord collection and a I want to check my ID in it.
#items_user_id = Item.select("DISTINCT user_id").where(:user_id => current_user.id)
and I check
#items_user_id.include?(params[:id])
returned nil
What's wrong?
UPD 1 : What I need - param[:id] contains id of Item. The user can edit the items created by them only. And I want to check whether the item identifier in the identifier pool items user.

In short: you are comparing Apples to Oranges.
Long Answer:
#items_user_id = Item.select("DISTINCT user_id").where(:user_id => current_user.id) this line will return Array of Item elements.
params[:id] would possibly be String or Integer so it would not be found in the Array.

The select you do executes this query:
SELECT DISTINCT user_id FROM items WHERE user_id = ?
That will yield either nothing, or a single row with just the user_id.
What do you really want?

Try to collect the ids from the array obtained and then check..
#items_user_id.map(&:id).include?(params[:id])
Make sure the datatype of ids(string) matches with params[:id]

Related

Laravel query builder - Select elements unique or null on specific column

I have a model Form for table forms. There is a column called guid which can be null, or contain some sort of grouping random hash.
I need to select all forms that have column guid either null or unique in current search. In other words, for repeating guid values in current search I select only first occurence of every guid hash.
I tried:
$results = App\Form::where(... some where clauses .. ).groupBy('guid')
and it's almost ok, but for all rows, where guid == NULL it groups them and selects only one (and I need all of them).
How can I get the unique or null rows either by building proper SQL query or filtering the results in PHP?
Note: I need my $results to be an Illuminate\Database\Eloquent\Builder instance
EDIT:
I fount out that SQL version of query I need is:
SELECT * FROM `forms` WHERE .... GROUP BY IFNULL(guid, id)
What would be equivallent query for Laravel's database query builder?
UPDATE: Using DB::raw
App\Form::where(... conditions ...)
->groupBy(DB::raw("IFNULL('guid', 'id')"));
Or the another way could be:
You can also use whereNotNull, whereNull & at last merge both the collections using merge() like this:
First get the results where guid is grouped by (excluding null guid's here):
$unique_guid_without_null = App\Form::whereNotNull('guid')->groupBy('guid')->get();
Now, get the results where guid is null:
$all_guid_with_null = App\Form::whereNull('guid')->get();
and at last merge both the collections using merge() method:
$filtered_collection = $unique_guid_without_null->merge($all_guid_with_null);
Hope this helps!
For your edited question, you can use raw() as;
->groupBy(DB::raw("IFNULL('guid', 'id')"))
So your final query will be as:
$results = App\Form::where(... some where clauses .. )
->groupBy(DB::raw("IFNULL('guid', 'id')"));
By above query, your $results will be an instance of Illuminate\Database\Eloquent\Builder.

select two calculations with one query in active record

In SQL I would do a "select count(*), min(price) from products". What is the best way to do this with one query in active records?
Right now I have to do two queries, which doesn't feel right.
result_count = Product.where(filter_string).count
result_min = Product.where(filter_string).minimum(:price)
You can add the string in a select method like this:
result_stats = Product.select("count(*) as product_count, min(price) as price_min").where(filter_string)[0]
result_stats["product_count"] # => 123
result_stats["price_min"] # => 12.35
The limitation here is that this will initialize Product objects with only those fields accessible (in this case only 1 object since there's no group by clause). In this case, it's not really an issue, but something worth knowing if you get an error when you try to access relations.
http://guides.rubyonrails.org/active_record_querying.html#selecting-specific-fields

Some help on a Union LINQ expression please

I need some help constructing a LINQ expression. I tend to use Lambda syntax.
I have 2 tables
OrderItem >- LibraryItem
OrderItem has a number of columns:
Id
FkLibraryItemId
Text
FkOrderId
LibraryItem has a number of Columns:
Id
Text
Type
Usually when selecting an "OrderItem", one picks a "Library Item". The "Id" and "Text" value are placed into the item record.
Sometimes a user may add a one off "OrderItem" which does not need storing in the "LibraryItem" table. It is simply stored in "OrderItem", but without a "FkLibraryItemId". So I have records in "OrderItem" that do not exist in "LibraryItem".
I need the LINQ to pull out all the relevant "LibraryItem" records of "Type=X" in addition to the "OrderItem" records for the relevant Order Id.
Many thanks in advance.
UPDATE:
I think I am talking about something like:
LibraryItem.Select(new{Id,Text}).Union(Order.Select(new{Id, Text})
context.OrderItems.Include("LibraryItems")
.Where(o => o.OrderId == orderId
&&(o.LibraryItem != null ? o.LibraryItem.Type == "X" : true))
Linq-to-SQL has a different syntax for Include, which basically eager-loads the reference objects (probably LoadWith, I don't remember at the moment).
Actually you can also do it with left inner join.

How to create an value array for a specific key in ruby hash?

There are user and user_level models in our rails app. In user_level there is a field called user_group_id. The relationship is userhas_manyuser_levels. We would like to generate an array of the user_group_id (in user_level) for a given user_id.
For a given user_id, its user_levels could be retrieved as :
u = User.find(user_id)
ul = u.user_levels
There may be multiple user_levels for a user. How to create an array of user_group_id from ul with ruby map (or some other ruby method(preferable ruby))? thanks.
Try this,
user = User.find(user_id)
user.user_levels.pluck(:user_group_id)
or this,
user.user_levels.map(&:user_group_id)
The first makes a separate database query selecting just the :user_group_id. For example, in MySQL it would call SELECT user_levels.user_group_id ....
The second collects the :user_group_id from the fetched user_levels.
You are indeed looking for map
user_group_ids = ul.map{|x| x.user_group_id}
Or with the shorthand:
user_group_ids = ul.map(&:user_group_id)
You might also want to have only different ids and no nils
user_group_ids = ul.map(&:user_group_id).uniq.compact

Imroving/Modifying LINQ query

I already have a variable containing some groups. I generated that using the following LINQ query:
var historyGroups = from payee in list
group payee by payee.Payee.Name into groups
orderby groups.Key
select new {PayeeName = groups.Key, List = groups };
Now my historyGroups variable can contain many groups. Each of those groups has a key which is a string and Results View is sorted according to that. Now inside each of those groups there is a List corresponding to the key. Inside that List there are elements and each one those element is an object of a particular type. One of it's fields is of type System.DateTime. I want to sort this internal List by date.
Can anyone help with this? May be modify the above query or a new query on variable historyGroups.
Thanks
It is not clear to me what you want to sort on (the payee type definition is missing as well)
var historyGroups = from payee in list
group payee by payee.Payee.Name into groups
orderby groups.Key
select new {
PayeeName = groups.Key,
List = groups.OrderBy(payee2 => payee2.SomeDateTimeField)
};
Is most straightforward.
If you really want to sort only by date (and not time), use SomeDateTimeField.Date.
Inside that List there are elements and each one those element is an object of a particular type. One of it's fields is of type System.DateTime
This leads me to maybe(?) suspect
List = groups.OrderBy(payee2 => payee2.ParticularTypedElement.DateTimeField)
Or perhaps even
List = groups.OrderBy(payee2 => payee2.ObjectsOfParticularType
.OfType<DateTime>()
.FirstOrDefault()
)
I hope next time you can clarfy the question a bit better, so we don't have to guess that much (and come up with a confusing answer)

Resources