Using rails , what 's wrong with this query , it does not return a valid id - ruby-on-rails-5

store_id=Store.select(:id).where(user_id:current_user.id).to_a.first
it returns id like that : Store:0x00007f8717546c30

Store.select(:id).where(user_id:current_user.id).to_a.first
select does not return an array of strings or integers for the given column(s), but rather an active record relation containing objects with just the given field:
https://apidock.com/rails/ActiveRecord/QueryMethods/select
Your code is then converting that relation to an array, and taking the first object in that array, which is an instance of the Store class. If you want the ID, then try:
Store.select(:id).where(user_id:current_user.id).to_a.first.id
However, I think you're misunderstanding how to structure the queries. Put the where part first, and then find the ID of the first result:
Store.where(user_id: current_user.id).first.id
And if there is only 1 store, then:
Store.find_by(user_id: current_user.id).id
Or...
Store.find_by(user: current_user).id
or.....
current_user.store.id
(or current_user.stores.first.id if there are many)

Related

How to Select value By SuiteQL That I can filter Multiple Select Field

I had one simple table ItemMapping, 2 Field, one Field is single Item List Field SingleSelectField With value "A",
Other for Multiple Item List Field MultiSelectField with Value ("B", "C", "D").
I Wanna get This mapping relationship By "B", I tried to set up one dataset, And try some single SuiteQL like before, But I always get empty results returned.
SELECT *
FROM ItemMapping
WHERE ItemMapping.MultiSelectField IN ('B')
Any tips may Help me.
Thank you in advance.
As was pointed out, Marty Zigman's article describes how Boban D. located an undocumented "feature" of SuiteQL which can be used.
I will leave most of the explaining to the article but to summarize, NetSuite automatically creates a relationship table named map_sourcTableId_fieldId which contain two columns: mapone and maptwo. mapone is the record id from the source table and maptwo is record id for the joined table.
This method seems to work well and maybe the most straight forward if you are accustomed to working in SQL.
As an alternative, I constructed a native SuiteScript Query object with a condition on a multiple select field. Then I used the toSuiteQL() method to convert it into SuiteQL to see how NetSuite natively deals with this. What I found was another undocumented "feature". The resulting query used a BUILTIN.MNFILTER function. So for example if you've got a custom transaction body field, custbody_link_type, that is a multiple select field and want to get transactions where one of te values in custbody_link_type is 4 then here is the generated SuiteQL:
SELECT T.tranid, T.custbody_link_types
FROM "transaction" as T
WHERE BUILTIN.MNFILTER(T.custbody_link_types , 'MN_INCLUDE', '', 'FALSE', NULL, 4) = 'T'
And if you want transactions where the custbody_link_types does not contain all of the following: 1, 2, 3 ...
SELECT T.tranid, T.custbody_link_types
FROM "transaction" as T
WHERE BUILTIN.MNFILTER(T.custbody_link_types , 'MN_EXCLUDE_ALL', '', 'FALSE', NULL, 1, 2, 3) = 'T'
OR T.custbody_link_types IS NULL
To wrap it up, the undocumented BUILTIN.MNFILTER function is used by NetSuite's query module to filter multiple select fields. It accepts the multiple select column, the internal string value of the query.Operator enum, some other stuff I don't know anything about, and finally one or more the values to compare. It appears to return a string of either 'T' for when the condition is met otherwise 'F'.
Ultimately, I'm not sure whether this is a "better" way to address the need but I thought it was worth documenting.

Rails: Need to scope by max version

I have this problem, I've got database table that looks like this:
"63";"CLINICAL...";"Please...";Blah...;"2014-09-23 13:15:59";37;8
"64";"CLINICAL...";"Please...";Blah...;"2014-09-23 13:22:51";37;9
The values that matter are the second to last and last one.
As you can see, the second to last (abstract_category_numbers) are the same, but the last differs (version_numbers)
Here is the problem:
When I make a scope, it returns all of the records, which i need to focus on the one with the maximum version number.
In SQL i would do something like this:
'SELECT * FROM Category c WHERE
NOT EXISTS SELECT * FROM Category c1
WHERE c.version_number < c1.version_number
AND c.abstract_category_id = c1.abstract_category_id'
But i'm totally lost at Ruby, more specifically how to do this kind of select in the scope (I understand it should be a relation)
Thanks
We can create a scope to select the category with max version_number like this:
scope :with_max_version_number, -> {
joins("JOIN ( SELECT abstract_category_id, max(version_number) AS max_version
FROM categories
GROUP BY abstract_category_id
) AS temp
ON temp.abstract_category_id = categories.abstract_category_id
AND temp.max_version = categories.version_number"
)
}
Basically, we will select the category with the max_version value on temp table in the subquery.
Btw, I expect the table name is categories, you may correct it. Then the final query will be:
Category.with_max_version_number
Scopes are suppose to return an array of values even if there is only 1 record.
If you want to ALWAYS return 1 value, use a static method instead.
def self.max_abstract_category
<your_scope>.max_by{ |obj| obj.version_number }
end
If I understand your question: you have a database table with a version_number column, which rails represents using an Active Record model--that I'll call Category because I don't know what you've called it--and you want to find the single Category record with the largest version_number?
Category.all.order(version_numbers: :DESC).limit(1).first
This query asks for all Category records ordered by version_number from highest to lowest and limits the request to one record (the first record, a.k.a the highest). Because the result of this request is an array containing one record, we call .first on the request to simply return the record.
As far as I'm aware, a scope is simply a named query (I don't actually use scopes). I think you can save this query as a scope by adding the following to your Category model. This rails guide explains more about Scopes.
scope :highest_version, -> { all.order(version_numbers: :DESC).limit(1).first }
I join implementation with baby_squeel but for some reason it was very slow on mysql. So I ended up with something like:
scope :only_latest, -> do
where(%{
NOT EXISTS (SELECT * FROM Category c
WHERE categories.version_number < version_number
AND categories.abstract_category_id = abstract_category_id')
}
end
I filed a BabySqueel bug as I spent a long time trying to do in a code proper way to no avail.

Group by an array's element in PostgreSQL

In Postgres 8.3, I need to group by certain elements within an array field. When I group by the array itself, all possible combinations are shown. I only want to group by the element.
something like this works for finding the count of a single element:
SELECT count(*)
FROM table
WHERE foo=any(bar)
this will return the correct count for a single element in an array. How do I return multiple counts for all elements in an array? If I group by the array, it will use all array elements in the identical order they are stored (not what I need).
edit for clarity:
bar is an array with values like {foo, some, thing} or {foo, thing} or {some, thing, else}
I want to know how many records have an element value of foo, some, thing, and else in the array "bar".
Something like
GROUP BY bar[4]
Hm.. you can't group by a value.. but of course the value is the column that contains it...
So.. you might want this:
SELECT AVG(blah), foo
FROM whatever
WHERE foo=any(bar)
GROUP BY foo
should work..

Find a string within an array column in PostgreSQL

I have built a series of views in a PostgreSQL database that includes a couple of array columns. The view definition is as follows:
create view articles_view as
(select articles.*,
array(select row(people.*)::people
from people
where articles.spubid=people.spubid and
people.stype='Author' and
bactive='t'
order by people.iorder) as authors,
array(select row(people.*)::people
from people
where articles.spubid=people.spubid and
people.stype='Editor' and
bactive='t'
order by people.iorder) as editors,
array(select row(people.*)::people
from people
where articles.spubid=people.spubid and
people.stype='Reviewer' and
bactive='t'
order by people.iorder) as reviewers,
array(select row(status.*)::status
from status
where articles.spubid=status.spubid and
bactive='t') as status
from articles
where articles.bactive='t');
Essentially what I want to do is an iLike on the 'author' column to determine if a specific user id exists in that array. Obviously I can't use iLike on that datatype so I need to find another approach.
Here is an example of data in the 'authors' array:
{"(2373,t,f,f,\"2011-08-01
11:57:40.696496\",/Pubs/pubs_edit_article.php,\"2011-08-09
15:36:29.281833\",000128343,A00592,Author,1,Nicholas,K.,Kreidberg,\"\",123456789,t,Admin,A,A,A,0,\"\")","(2374,t,f,f,\"2011-08-01
11:57:40.706617\",/Pubs/pubs_edit_article.php,\"2011-08-09
15:36:29.285428\",000128343,A00592,Author,2,John,D.,Doe,\"\",234567890,t,IT,A,A,A,0,\"\")","(2381,t,f,f,\"2011-08-09
14:45:14.870418\",000128343,\"2011-08-09
15:36:29.28854\",000128343,A00592,Author,3,Jane,E,Doe,\"\",345678901,t,Admin,A,A,A,,\"\")","(2383,t,f,f,\"2011-08-09
15:35:11.845283\",567890123,\"2011-08-09
15:36:29.291388\",000128343,A00592,Author,4,Test,T,Testerton,\"\",TestTesterton,f,N/A,A,A,A,,\"\")"}
What I want to be able to do is a query the view and find out if the string '123456789' (that is the user id assigned to Nicholas Kreidberg in the array) exists in the array. I don't care which user it is assigned to or where it appears in the array, all I need to know is if '123456789' shows up anywhere in the array.
Once I know how to write a query that determines if the condition above is true then my application will simply execute that query and if rows are returned it will know that the user id passed to the query is an author for that publication and proceed accordingly.
Thanks in advance for any insight that can be provided on this topic.
Might this:
select ...
from ...
where ...
and array_to_string(authors, ', ') like '%123456789%';`
do the trick?
Otherwise, there is the unnest function...
The "Array Functions and Operators" chapter has more details.
The ANY() function can do the job for you:
SELECT * FROM people WHERE '123456789' = ANY(authors);
Given people.authors is of type text[].

NHibernate: row/result counting: Projection.RowCount() VS. Projection.Count()

What is the exact difference between NHibernates
Projection.RowCount()
and
Projection.Count()
when we are looking for number of rows/results?
Projection.Count expects you to pass a property that you want a count on i.e
Projection.Count("propertyName")
which transalates to the following in SQL
select Count(this.whateverNhibernateConvention) from table as this
where as for Projection.RowCount you dont need to pass anything which translates to
select Count(1) from table as this
I think I expect the above to be the case