rails delete unknown column - ruby-on-rails

I have a simple Model called Token that has a user_id (integer) attribute.
If I do this:
Token.where(:user_id => 1)
it returns a record. But when I do:
Token.delete(:user_id => 1)
it gives me this error:
ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 'id.user_id' in 'where clause': DELETE FROM `tokens` WHERE `id`.`user_id` = 1
For some reason it appends id to user_id in SQL statement. Why is it doing that? it works just fine for where clause.

delete expects an id or an array of ids:
Token.delete(1)
Token.delete([2,3,4])
To delete records matching a condition, use delete_all instead:
Token.delete_all(:user_id => 1)
You can also append it to your query:
Token.where(:user_id => 1).delete_all
Both delete all tokens with user_id 1.

What about reading some docs?
http://apidock.com/rails/ActiveRecord/Base/delete/class
delete(id) public

Token.delete_all("tokens.user_id = ?", 1)

Token.delete expects a record ID, not condition hash (documentation).
You want something like this:
Token.where(:user_id => 1).delete_all

Related

Postgres - Group by multiple columns, Rails

I have a table named property_audit_version_histories.
i am fetching the records using the following code
#version_logs = PropertyAuditVersionHistory
.includes(:property_audit_version, :user)
.where(property_audit_version_id: params[:id])
The result contain 3 records, 2 of which have the same action and user_id
Now i need to group the records using the columns action, user_id
I am getting the following error when i try to group the records
#version_logs = PropertyAuditVersionHistory
.includes(:property_audit_version, :user)
.where(property_audit_version_id: params[:id])
.group("action, user_id")
PG::GroupingError: ERROR: column "property_audit_version_histories.id" must appear in the GROUP BY clause or be used in an aggregate function
Based on the thread PG::GroupingError: ERROR: column "events.id" must appear in the GROUP BY clause or be used in an aggregate function i have modified the code as follows
#version_logs = PropertyAuditVersionHistory
.includes(:property_audit_version, :user)
.group("property_audit_version_histories.id")
.where(property_audit_version_id: params[:id])
.group("action, user_id")
Now the error is gone but still the result is having 3 records. After grouping i expect only 2 records.
Any idea on how to fix this?
You cant select all columns like mysql in postgresql when doing aggregrates.
So I guess this should work.
#version_logs = PropertyAuditVersionHistory
.where(property_audit_version_id: params[:id])
.group("action", "user_id", "property_audit_version_id")
.select("user_id", "action", "property_audit_version_id")
I dont know how is your model but this should work. If you need more fields let me know
What you need to do is specify which columns you want with
.select("user_id")
But for the columns you know will be the same use max(columnName) as columnName
for example:
.select("MAX(user_id) as user_id, action")
Make sure you are 100% sure that those columns will be the same value after grouping.

How to use Activerecord find([34,183]) with the conditions

In the Activerecord rails where we use find[(a,b)] to get all the rows that has ids between a and b. How to add condition to this function where we can match 'id' column with matching certain integer.
I tried below code but is not working.
User.find([34,183], :conditions => {:id => 4}).
See the docs regarding range conditions:
User.where(id: 34..183)
This will generate the following SQL statement:
SELECT * FROM users WHERE (users.id BETWEEN '34' AND '183')
To append the results of another ActiveRecord where query, use the merge method:
users = User.where(id: 34..183)
user = User.where(id: 4)
users.merge(user)

Why does it recognize as Unknown Column?

I'm trying to sort ordered by updated_at of User record, which is associated from Code table.
#codes = Code.joins(:user).where('body like ?', "%"+params[:search]+"%").order('user.updated_at DESC').page(params[:page]).per(10)
However, it won't let me sort:(
This is the error message I get.
Error Message
Mysql2::Error: Unknown column 'user.created_at' in 'order clause
Your database table should be users not user (plural not singular). Update your order method as follows:
order('users.updated_at DESC')

How to get the inverse of where ids => collection of ids in Rails

I'm trying to return the inverse of this statement:
scope :subscribed, lambda {|user| where(:venue_id => user.flagged_venues)}
flagged_venues returns an array of ids, so when I run that statement I get all of the flagged venues. What I actually want is the exact opposite: all the venues except for the flagged ones.
I tried it with != instead of => but that returned all the venues.
When it's changed to where("venue_id <> ?", user.flagged_venues) then I get this error: PG::DatatypeMismatch: ERROR: argument of WHERE must be type boolean, not type record LINE 1: SELECT "events".* FROM "events" WHERE (venue_id <> 2,4)
You want the ids that are not in the list of flagged_venues, so my guess is that you should replace
where(:venue_id => user.flagged_venues)
by
where("venue_id not in (?)", user.flagged_venues)

How to retrieve values from a column called "object_id" in ActiveRecord?

I need to access a legacy relational database via ActiveRecord and that database uses a column named "object_id" as a primary key in a table. Most things work but when I try specify a custom SQL query for an association (see below) ActiveRecord respectively the Ruby interpreter always retrieves the object_id of the Ruby base "Object" instead of the column value from the database.
I defined the following SQL query in a has_many declaration:
:finder_sql => "SELECT * FROM t_object WHERE object_id IN (SELECT end_object_id FROM t_object, t_connector WHERE t_object.object_id = #{object_id} AND start_object_id = #{object_id})
I already tried to solve it by working with an alias:
alias_attribute :my_oid, :object_id
and using "my_oid" in the SQL query. But I got the following error message:
NameError: undefined local variable or method `my_oid' for EaTObject(Table doesn't exist):Class
I also defined a method which returns the value of read_attribute("object_id") and put the method name into the SQL query instead of "object_id" but when the class was loaded I got the error message that that method name is not a column name in the database table.
Is there any solution to access a column called "object_id"?
You can use this method:
read_attribute(:object_id)
The link in documentation :
http://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Read.html#method-i-read_attribute
So if you want access to your object_id column whan you call oid you need delete your alias and define the oid method
def oid
read_attribute(:object_id)
end
Another option is self[:object_id], but if you are getting "Table doesn't exist", then maybe there is something else wrong?
Edit:
Try this:
:finder_sql => 'SELECT * FROM t_object WHERE object_id IN (SELECT end_object_id FROM t_object, t_connector WHERE t_object.object_id = #{id} AND start_object_id = #{id})'
NB! single quotes.
You may use t_object.object_id in your SQL to specify object_id field, or you may alias your t_object table, e.g.
:finder_sql => "SELECT * FROM t_object AS t WHERE t.object_id IN..."
If you want to execute a select like I had to, I'd suggest using an alias for the column name to get it working as expected.
sql selects the unique id number for the object within the database, if you want to select the value instead, you can do using this
SELECT books.object_id as obj_id FROM books

Resources