3

I have a SQL query in a Rails model that responds with an array of objects. And each object has an attribute called points with a value.

But its preferable for query to just return an array of points like [10,15,5] instead of [object,object,object] which requires then extracting the points out into another array to be useful.

Model file

LAST_3_SELECT = "
  SELECT
    (
      (data.ap / (data.apa * 1.0))
      +
      (data.vp / (data.vpa * 1.0))
    )
    / 2 * 1.5 * data.level
    AS points
  FROM data
  WHERE data.user_id = ?
  GROUP BY data.id
  ORDER BY data.created_at DESC
  LIMIT 3
"

def self.last_3(user_id)
  connection.select_all(sanitize_sql_array( [LAST_3_SELECT, user_id]), "last-3")
end

Is this possible to do in a query itself, or necessary to do in a method outside it?

I don't have much experience writing raw SQL queries into Rails methods so any guidance would be very appreciated.

3
  • Why not just make an addiitional map call? Commented May 8, 2016 at 5:35
  • For .map(&:points), it returned NoMethodError (undefined method 'points' for {"points"=>2.4000000000000004}:Hash): Commented May 8, 2016 at 6:56
  • 1
    Just do .map{ |row| row["points"] } Commented May 8, 2016 at 6:58

1 Answer 1

4

You can use pluck to get the points into an array

def self.last_3(user_id)
  connection.select_all(sanitize_sql_array( [LAST_3_SELECT, user_id]), "last-3").pluck(:points)
end

Here points is the column name to be plucked

Sign up to request clarification or add additional context in comments.

4 Comments

NoMethodError (undefined method 'pluck' for #<ActiveRecord::Result:...>)
Instead of .pluck(:points) use .collect(&:points). This will get you the list of pints in array.
@pandaman, for the active record result, is this working, result.first.points
Rails4. Tried .collect() and ran into something like NoMethodError (undefined method 'points' for {"points"=>...}:Hash). But was able to get it working using .map.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.