ActiveRecord update error - illegal zero-length identifier - ruby-on-rails

I'm running simple Rails + ActiveRecord program, where I want to take records from the database, where column "transfered_at" is null, and update it with the current time.
orders_ora = Orders.where(transfered_at: nil)
orders_ora.each do |order_ora|
puts order_ora.name
order_ora.update(transfered_at: Time.now)
end
However, it does not allow me to do that. Here is the error that I'm getting:
OCIError: ORA-01741: illegal zero-length identifier: UPDATE
"ORDERS" SET "TRANSFERED_AT" = :a1 WHERE
"ORDERS"."" IS NULL (ActiveRecord::StatementInvalid)
What am I missing?
Edit: I need to use this inside the loop because I'm doing other calculations inside it. And time format does not seems to be the problem, because I'm trying to update another column which type is "number", and I'm getting the same error.
If I try to do it like this:
order_ora.inspection_id = 333
order_ora.save
it also gives the same error as before.

Why do you loop through the results? You can do it in a single query:
Orders.where(transfered_at: nil).update(transfered_at: Time.now)
What could be a problem is that the Time.now is not in the correct format for your table? Use strftime in that case:
Orders.where(transfered_at: nil).update(transfered_at: Time.now.strftime('%H:%M') )

I found answer to this myself, it was not related to the code.
The problem was that my table did not have a PK, and it looks like ActiveRecords uses it to generate SQL statements.

Related

Rails - Querying a JSON Field

In my Rails 5 app, I'm using the Ahoy gem which uses a jsonb field (called properties) that I don't know how to query.
A sample of the data in the properties field:
"{\"id\":\"11\"}"
What I'm trying to do is:
Find the records created in the last seven days (using the time field)
Group the records by the id in the properties field
Order the records based on which id had the most records
I tried this:
#foo = Ahoy::Event.where(name: "Viewed Product").where(time: 7.days.ago..Time.now).group("properties(id)").order('COUNT("properties(id)") DESC')
but I received the error, PG::UndefinedColumn: ERROR: column "properties(id)" doe not exist
I found this somewhat similar question in the issues for the gem, so I tried breaking the query into parts:
#foo = Ahoy::Event.where(name: "Viewed Product").where(time: 7.days.ago..Time.now)
#foo.group("properties REGEXP '[{,]\"id\"...).count
but then my IDE gives the error unterminated string meets the end of file.
Can someone please help me determine what I'm doing wrong?
If you are using PostgreSQL, I believe that you would have to refer to json columns like this:
.group("properties ->> 'id'")

Rails 3 - .each works, .find_each fails -> ActiveRecord::JDBCError: ERROR: operator does not exist: character varying >= integer

I've got a lot (+100,000) of records I'm trying to process through a query.
I was using something like:
BigRecordPull.where(name: ['x','y','z']).each { |record| do_some_action record }
Because this isn't good from a memory management perspective, I wanted to instead use find_each as outlined here so now the code looks like this:
BigRecordPull.where(name: ['x','y','z']).find_each { |record| do_some_action record }
The issue is when I go to fire the code I get the following error:
ActiveRecord::JDBCError: ERROR: operator does not exist: character varying >= integer
Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.
If I review the SQL query created in the logs I get back something like:
SELECT "big_record_pull".* FROM "big_record_pull" WHERE "big_record_pull"."name" IN ('x','y','z') AND ("big_record_pull"."name" >= 0)
ActiveRecord seems to add the part, 'AND ("big_record_pull"."name" >= 0)' and that seems to be what's causing the problem. Name in this example is a varchar. The extra wrinkle is I don't control the postgresql db my rails project plugs into so I can't just re-run a migration to try and fix this issue. I'm hoping there's some sort of work around.... I'd like to avoid running raw SQL.
Extra info
In the example above, big_record_pull.name is also a foreign_key
Ok, the problem was related to a gem: composite_primary_keys-5.0.14.gem.
Solution was found, here
See lib/composite_primary_keys/relation/batches.rb:28:in `find_in_batches'
Change this block to:
self.primary_key.each do |key|
condition = case relation.columns_hash[key.to_s].type
when :string
table[key].not_eq ''
when :integer
table[key].gteq start
end
relation = relation.where(condition)
end

Where query with Time.now

I want to achieve the following:
Model.where("asdasd = ? AND to <= ?", nil, Time.now).each do |model|
I get the following error:
ActiveRecord::StatementInvalid: SQLite3::SQLException: near "to": syntax error: SELECT "bla".* FROM "table" WHERE (asdasd = NULL AND to <= '2015-11-09 10:18:14.777643')
I also use the same in another controller, where I get the same error. What would be the correct way to achieve what I want? I am also quite sure that it worked already like that, could there be any other thing which causes this issue?
Thanks!!!
TO is an SQL keyword, and needs to be quoted in a query. the list of SQLite keywords is avaiable in the SQLite documentation.
Other database engines have similar (but not identical) rules and lists of keywords, so if you change from SQLite then check the rules for whatever the new engine is.

active record how do I specify a column after a join?

I'm trying to make an sql query using activerecord and I'm having a hard time specifying a specific column from multiple joined tables.
for instance in sql
select go.id, sequence.name, sequence.id from sequence join (goterms,...) on ...
this is not beautiful sql but my point is that I'm able to specify which .id I want returned
in activerecord I'm doing this:
results = Sequence.joins(:Foreigndb,:Goterm,:Taxa)
.select(:header,:taxaclass, :genus, :interpro_desc,:description,:dbname,:read_depth, :name)
.distinct
I want to be able to get id from :Goterm but :Taxa and :Foreigndb also use id as a column in the database so i'm getting uninformative errors that I assume stem from this issue when I do the following.
results = Sequence.joins(:Foreigndb,:Goterm,:Taxa)
.select(:header,:taxaclass, :genus, :interpro_desc,:description,:dbname,:read_depth, :name,:id)
.distinct
What is the correct way to just specify that I want Goterm.id?
edit - Here is the error:
ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 'Goterm.id' in 'field list'
when I run:
results = Sequence.joins(:Foreigndb,:Goterm,:Taxa).select(:header,:taxaclass,:genus, :interpro_desc,:description,:dbname, :read_depth, :name,'Goterm.id').limit(5).offset(0).dresults = Sequence.joins(:Foreigndb,:Goterm,:Taxa).select(:header,:taxaclass, :genus, :interpro_desc,:description,:dbname, :read_depth, :name,'Goterm.id').limit(5).offset(0).distinct
results = Sequence.joins(:Foreigndb,:Goterm,:Taxa).select(:header,:taxaclass, :genus, :interpro_desc,:description,:dbname,:read_depth, :name, 'sequences.id')
.distinct
It turns out that ilan's answer is correct, however be sure that everything is lower case. I was using 'Goterm.id' to make the selection when it needs to be 'goterm.id'
If anyone else runs into this, I also ran into difficulties grabbing the goterm.id data out of the returned query objects. Each time I called object.id on that return set it would give me something different from what I was expecting. I think the attribute I was expecting was being obscured by something else. To get the data I needed I did the following:
results = Sequence.joins(:Foreigndb,:Goterm,:Taxa).select(:header,:taxaclass, :genus,:interpro_desc,:description,:dbname,:read_depth, :name).distinct
firstRes = results[0]
firstRes.attributes['id']

rails include with array of id on condition

I tried to find with array of value using where condition and includes.
But gettting some error..
the below works well and return beneficiary with user included
Beneficiary.includes(:user).where("beneficiaries.id = ?",304)
but when i try with array of ID i'm getting some error
Beneficiary.includes(:caterer_info).where("beneficiaries.id = ?",[304,305])
ActiveRecord::StatementInvalid: Mysql::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '304,305)'
Try the following.
Beneficiary.includes(:caterer_info).where({beneficiaries: {id: [304,305]}})
Why dont you try with where method instead of find_all_by_id
Beneficiary.includes(:caterer_info).where('beneficiaries.id IN (?)', [304,305])
found the answer on my own
Beneficiary.includes(:user).where("beneficiaries.id IN (?)",ids)
Thanks

Resources