I'm trying to select the User Id as a variable in the console however I keep ending up with:
[#<User id: 4>]
The find statement I have tried is:
userid = User.select('id').where('username = ?', 'uwZgf')
I've also tried with find_by_sql with same result.
What do I need to get the value out instead of the hash?
What you've got there is an array of one User object.
User.select(...).where(...).first.id
Would do the trick (you'd probably want to check the value returned by first before trying to call id on it.
You might find
User.find_by_username('foo').try(:id)
more readable.
Related
I was wondering if there is a way to use a select statement with a where clause similar to this way that does not seem to work for me in Ruby version 2.0/Rails 4.0 trying to retrieve a single record string value of a city where the building name is a certain name:
building_city = Building.select(:city).where(building_name: building).uniq
I have also tried:
building_city = Building.select(:city).where(building_name: building).distinct
Currently I have my code working like this:
building_city = Building.where(building_name: building).first
This grabs an entire Building object, and then I can call the city by doing a:
building_city.city
This works fine with what I am trying to achieve, but I was wondering if there is a smarter way to do this. Specifically, I was wondering if there is a way to grab only the string value of a city where the building name equals a certain building and store it into a variable?
Any help/advice is greatly appreciated! :)
Are you perhaps looking for pluck? Something like:
cities = Building.where(building_name: building).uniq.pluck(:city)
That will perform this SQL:
select distinct city from buildings where building_name = '...'
and give you the cities as an array of strings. You'll still get an array but a quick first call will take care of that if you're certain that there will only be one entry.
building_city = Building.select(:city, :building_name).where(building_name: building).uniq — you need to include the building_name
city = Building.where(building_name: building).pick(:city)
Rails 6 introduced pick method with works like where(..).pluck(..).first. Docs
I'm using Ruby on Rails and PostgresQL
I have this query for finding the last value in a table with a specific device attribute value that works great:
Positions.where(device_id: 3).last
However, now I need to query for the last value for each of multiple devices. I'm pretty sure there is a way to do this more efficiently than calling the last for each device value separately.
How can I combine this:
Positions.where(device_id: 3).last
Positions.where(device_id: 5).last
Positions.where(device_id: 23).last
I've tried searching here and in the documentation. I've read and tried some 'group' and 'having' methods, but to no avail.
Try this update..
device_ids = [3,5,23]
Positions.where(device_id: device_ids).group(:device_id).maximum(:id)
It returns a Hash, to get the Position records, you can
device_ids = [3,5,23]
last_positions = Position.where(id: Positions
.where(device_id: device_ids)
.group(:device_id)
.maximum(:id).values)
so I'm looking at creating a filter for a JSONAPI resource where I'll grab anything created within the last 10 minutes and return only one result if something's there.
Problem, when I call .last(1) on the returned records I get an error:
"exception": "undefined method `order' for #<Array:0x007fde4770bcf0>"
My non-breaking query is this:
records.where(user_id: user_id, updated_at: ten_minutes_ago..current_time)
Any help? I'd like to do this on the Rails-side rather than deal with a mangle of results (or no results) on our front-end. Thanks!
Okay, so the deal is this.
In order to grab only 1 record you'll probably have to overwrite/define your own paginator, like so:
paginator :none
I'd put it after your attributes and before your filters. Cool? Cool. Next, you can just do your basic Rails querying:
records.where(user_id: user_id, updated_at: ten_minutes_ago..current_time)
.order(id: :desc)
.limit(1)
You need to set your paginator or else the defaults or whatever you've defined will overwrite your limit query. Sweet. Easy.
I'm missing something simple - I do not want to access the results of this query in a view.
Here is the query:
#adm = Admin.where({:id => {"$ne" => params[:id].to_s},:email => params[:email]})
And of course when you inspect you get:
#adm is #<MongoMapper::Plugins::Querying::DecoratedPluckyQuery:0x007fb4be99acd0>
I understand (from asking the MM guys) why this is the case - they wished to delay the results of the actual query as long as possible, and only get a representation of the query object until we render (in a view!).
But what I'm trying to ascertain in my code is IF one of my params matches or doesn't match the result of my query in the controller so I can either return an error message or proceed.
Normally in a view I'm going to do:
#adm.id
To get the BSON out of this. When you try this on the Decorated Query of course it fails:
NoMethodError (undefined method `id' for #<MongoMapper::Plugins::Querying::DecoratedPluckyQuery:0x007fb4b9e9f118>)
This is because it's not actually a Ruby Object yet, it's still the query proxy.
Now I'm fundamentally missing something because I never read a "getting started with Ruby" guide - I just smashed my way in here and learned through brute-force. So, what method do I call to get the results of the Plucky Query?
The field #adm is set to a query as you've seen. So, to access the results, you'll need to trigger execution of the query. There are a variety of activation methods you can call, including all, first, and last. There's a little documentation here.
In this case, you could do something like:
adm_query = Admin.where({:id => {"$ne" => params[:id].to_s},:email => params[:email]})
#adm_user = adm_query.first
That would return you the first user and after checking for nil
if #adm_user.nil?
# do something if no results were found
end
You could also limit the query results:
adm_query = Admin.where( ... your query ...).limit(1)
Suddenly I've realized that while this works in groovy just like it is expeceted:
Sql.newInstance(connectionParams).rows("SELECT FROM ITEMS WHERE id = ?", [200])
this won't work
Sql.newInstance(connectionParams).rows("SELECT FROM ITEMS WHERE name LIKE '%?%'", ["some"])
All you can get is
Failed to execute: SELECT FROM ITEMS WHERE name LIKE '%?%' because:
The column index is out of range: 1, number of columns: 0.
My questions are:
Is it intentionally implemented this way? I've never needed to have a parametrized text search, so I'm not sure where this behaviour is typical or not.
How can I nevertheless safely parametrize statement with text search in it?
I believe you want to include the %'s in the parameter, like:
Sql.newInstance(connectionParams).rows("SELECT FROM ITEMS WHERE name LIKE ?", ["%some%"])