How to use select in findAllByAttributes in Yii - yii

I have seen this:
$makeModels = Make::model()->findAll(array("select"=>"fieldMake", "order"=>"fieldMake DESC"));
is it possible to do so with findAllByAttributes too? I need to only select one column values. I mean I don't want findAllByAttributes return array of object I need only an array of values.

If you only want an array of values use a custom SQL command with CDbCommand
Take a look at the following url for more information:
http://www.yiiframework.com/doc/api/1.1/CDbCommand
It will probably look something like this:
Yii::app()->db->createCommand('your sql query')->queryColumn();

Related

Can't quote array - rails sql

Im trying to create a sql query dynamically with the following syntax:
Company.joins(:founder_persons)
.where("people.first_name like people[:first_name]", {people: {first_name: 'm%'}})
But running this on the rails console gives me TypeError: can't quote Array. Im guessing this is not how we use the where string? What's the right way to fix this error? Thanks.
One reason this error can occur is with a nested array used as SQL value.
Example:
Article.where(author: ['Jane', 'Bob'])
works, but:
Article.where(author: ['Jane', ['Bob']])
would give the error. A quick fix would be to run flatten on the array.
(Mentioning this since this page comes up when searching for the confusing error "Can't quote array".)
You could bind any value and then assign it, this way they should coincide in numbers, like:
Model.joins(:join_table)
.where('models.first_attribute LIKE ? AND models.second_attribute LIKE ?', value_for_first_attr, value_for_second_attr)
If using an array you should access each index you want to compare, or you can precede a splat *, and specify just one value, like:
Model.joins(:join_table)
.where('models.first_attribute LIKE ? AND models.second_attribute LIKE ?', *array_of_values)
Note although this way you're passing the "whole" array it should also coincide in size or numbers, otherwise it'd raise an ActiveRecord::PreparedStatementInvalid error depending if there are more or less elements than needed.

Rails 3 : Use model method while using sum()

I am new to rails. I am trying to figure out how to use model method inside the sum() sql function. I tried searching for the solution but couldn't find one. Here's the code snippet :
SUM(indents.total_payable_amount_paid) AS sum_comm_t_amount_payable_paid
I want to use method called total_payable_amount_paid defined inside indent model. But it always gives an error:
PGError: ERROR: column indents.total_payable_amount_paid does not exist.
So what's the solution for this problem? Thanks in advance!
The problem is that your SUM (which i assume it's in a query string) takes indents.total_payable_amount_paid as part of that string.
To avoid that you could use string interpolation to set the value you want, like this:
"SUM(#{indents.total_payable_amount_paid}) AS sum_comm_t_amount_payable_paid"
So, lets say indents.total_payable_amount_paid returns 250, then the above code will generate this string:
"SUM(250) AS sum_comm_t_amount_payable_paid"
But, using SUM will make no effect, since you are giving one value, so you can accomplish the same thing without it:
"#{indents.total_payable_amount_paid AS sum_comm_t_amount_payable_paid"
#=> "250 AS sum_comm_t_amount_payable_paid"

Using find_by_sql in range gives error: undefined method `value_for_database' for "2017-01-01":String

This error showed up when I was trying to search from a range of date.
This is my model:
def self.search(search)
if search
#policies = Policy.find_by_sql("acct_ent_date IN ?", start_date..end_date)
else
limit(10)
end
end
Just to help out anyone else coming here: If you want to use query params with find_by_sql, you need to put all the arguments into an array, like this:
Policy.find_by_sql(["acct_ent_date IN ?", start_date..end_date])
I've never actually seen passing a range as a query parameter, so I can't comment on that, but in general the "undefined method `value_for_database'" error comes from not wrapping the arguments in an array.
You rarely need to drop down to writing raw SQL in rails (e.g. using the find_by_sql method) - especially for such a simple query as this.
Instead, you can just write the following and ActiveRecord will correctly convert it to valid SQL syntax for you:
# If you are looking for a list of all matching entries:
Policy.where(acct_ent_date: start_date..end_date)
# If you only wish to fetch the FIRST matching entry:
Policy.find_by(acct_ent_date: start_date..end_date)
This will generate SQL like the following:
SELECT `policies`.* FROM `policies` WHERE (`policies`.`acct_ent_date` BETWEEN xxxxx AND yyyyy)
The key problem with your original (raw SQL) code is that you are using WHERE IN syntax - which is really just shorthand for multiple OR conditions. This does not make sense to use with a Range (start_date..end_date) object, as this is not a discrete list (i.e. an Array).
If you were to attempt to convert your object into an array, you would see an error something like this:
(start_date..end_date).to_a # => TypeError: can't iterate from Time

Rails query the last of each type

I am using STI and have a table Widget that a bunch of other subclasses inherit from using STI. I want a query that gets the last created of each object with a uniq type.
I have a predefined array of types I want so lets say:
types = ["type1", "type2", "type3"]
So my query would be something like: (this doesnt work)
Widget.where(type: types).uniq.reverse
My goal is to get the last of each object that matches 1 of those types..
Not 100% sure, but something like this might work (untested):
ids = Thing.where(type: types).group(:type).maximum(:id).values
last_per_type = Thing.find(ids)
Thing.select("distinct type")
By the way, type is a special variable in rails and can't be used as a column name.

Checking existence of value inside JSON array

I've found the solution for more complex than this but I'm not able to make this work...
I've a column called data of type json. The JSON structure is as follows:
{"actions": ["action1","action2","action3", ..., "actionN"]}
So, let's say I've 3 rows with the following data:
{"actions": ["work","run"]}
{"actions": ["run","eat","sleep", 'walk']}
{"actions": ["eat","run","work"]}
I want to retrieve the rows where work is included in actions array.
I've tried something similar to what is posted here:
Query for element of array in JSON column, but since each element inside the array is just a json string, I got stuck there.
Then, I tried something like:
SELECT * from table t WHERE 'work' in ...
but this also failed to get the values as an string array to put it there.
Using PostgreSql 9.3.
Since you are using the json type, which is just a string internally, the simplest solution is:
SELECT * FROM table WHERE strpos(data::text, 'work') > 0;
It defeats the purpose of using json in the first place, but it is (very likely) faster than the json parser in this simple case.
A json solution would be:
SELECT * FROM (
SELECT *, unnest(data->"actions")::text AS action FROM table) AS foo
WHERE action = 'work';