rails difference between Model.count and Model.count(:all) - ruby-on-rails

Is there any difference between
User.count
and
User.count(:all)
I upgraded rails to 4.0 then when I use ModelName.count(:all) it's working well but if I use ModelName.count the following error occurs.By the way bot of them is working well in rails 3.2
SELECT COUNT() FROM "users"
PG::WrongObjectType: ERROR: count(*) must be used to call a parameterless aggregate function
LINE 1: SELECT COUNT() FROM "users"

I ran into this issue as well. The change was introduced in this commit. A line like
User.count
will now throw an ActiveRecord::StatementInvalid error since it will generate SELECT COUNT() FROM users on Postgres. As of this commit, the fix is to update your code to
User.count(:all)
This commit restores the functionality that existed previously, using :all as the "column" to pass on to ARel, causing a valid SQL query SELECT COUNT(*) FROM users.
My Gemfile originally had the following (as mentioned in the comments)
gem "rails", github: "rails/rails", branch: "4-0-stable"
but I needed to run bundle update rails to pull down the newer commit referenced above.

I guess there is no difference between them
http://apidock.com/rails/ActiveRecord/Calculations/count
http://api.rubyonrails.org/classes/ActiveRecord/Calculations.html#method-i-count
By not passing any parameters to count, it will return a count of all the rows for the model.

Related

Ruby: syntax error at or near "$1" using PG Gem [duplicate]

As far as i have seen the documentation on some statements dynamic operations are not allowed like if i want to execute the statement
res = conn.exec_params('CREATE DATABASE $1',[dbname])
i am getting this error
Error: ERROR: syntax error at or near "$1"
LINE 1: CREATE DATABASE $1
while if i use select statement SELECT * FROM pg_database WHERE datname = $1 this statement is successful.
While the above issue was not there with dbd/pg gem but it seems it hasnt been released from past 2010 which translate the dynamic paramters into native pg and with latest ruby and pg gem dbd/pg is not working.
My question is do we have any way with native PG gem to perform dynamic replacement of variables with create database, insert into like statements. OR is there any alternative for dbd/pg which offers same functionality?
Placeholders (i.e. $1, $2, ...) are for values. A database name (or table name, column name, ...) is an identifier. This is similar to the difference between a variable name and the value the variable holds in Ruby.
If you need to dynamically insert an identifier in some SQL then you need to use string interpolation and the special purpose quote_ident method to make sure you quote it properly. So something more like this:
db_name = conn.quote_ident(db_name)
res = conn.exec("CREATE DATABASE #{db_name}")

Create an ActiveRecord::Relation in rails 6 with a different table

I am trying to upgrade partitioned gem in order to use partitioning with Rails 6.1 (I am upgrading an existing Rails application).
I have managed to get everything to work, except for one part:
In partitioned gem, in order to query the partitioned table,
they would create a new relation with the "correct" arel_table (i.e - the actual partition table we want to query).
The following syntax worked with Rails 3.2:
def self.from_partition(*partition_key_values)
table_alias_name = partition_table_alias_name(*partition_key_values)
return ActiveRecord::Relation.new(self, self.arel_table_from_key_values(partition_key_values, table_alias_name))
end
Where self.arel_table_from_key_values(partition_key_values, table_alias_name) is an instance of Arel::Table pointing to the correct table name (partition).
I've updated the syntax to be:
def self.from_partition(*partition_key_values)
table_alias_name = partition_table_alias_name(*partition_key_values)
return ActiveRecord::Relation.new(self, table: self.arel_table_from_key_values(partition_key_values, table_alias_name))
end
The problem now is that when I try to run commands that worked in Rails 3.2 such as:
ItemLine.from_partition(11,1).find_by_code("1111")
I get errors such as undefined method `find_by_code' for #<ActiveRecord::Relation
Or if I try to run
ItemLine.from_partition(11,1).last
I get:
undefined local variable or method `implicit_order_column' for #<ActiveRecord::Relation
It seems like I am creating the relation in a wrong way.
What is the best/correct way to create an ActiveRecord::Relation with a different arel table in Rails 6.1?
Thanks!
After digging around in the source code of ActiveRecord,
I was able to solve it in the following way:
def self.from_partition(*partition_key_values)
table_alias_name = partition_table_alias_name(*partition_key_values)
table = self.arel_table_from_key_values(partition_key_values, table_alias_name)
tm = ActiveRecord::TableMetadata.new(self,table)
predicate_builder = ActiveRecord::PredicateBuilder.new(tm)
return ActiveRecord::Relation.create(self, table: table, predicate_builder: predicate_builder)
end
I still need to run some tests on this solution, but so far so good! :-)

Activerecord Model.table_exists? does not give correct results

When creating the actual database table in rails console, User.table_exists? does not give me the correct result.
But when I look into ActiveRecord::Base.connection.tables it shows that the table exists. I have to exit rails console and go back in before User.table_exists? give me the correct value. Is there some caching going on? A bug in Rails 5.2.1? Or am I missing something?
Code to reproduce:
in terminal/bash
rails generate model User name:string
rails console
in rails console
User.table_exists? => false
ActiveRecord::Base.connection.tables => []
ActiveRecord::Migration[5.2].create_table :users =>
-- create_table(:users)
(0.1ms) SELECT sqlite_version(*)
(1.5ms) CREATE TABLE "users" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL)
ActiveRecord::Base.connection.tables => ["users"]
User.table_exists? => false
exit
in terminal/bash
rails console
in rails console
User.table_exists? => true
using:
Ruby 2.5.0
Rails 5.2.1
ActiveRecord::ModelSchema::ClassMethods#table_exists? is a wrapper around ActiveRecord::ConnectionAdapters::SchemaCache#data_source_exists?.
As the name implies, this is a cache, probably populated when the Rails app starts. If you modify the database schema the old schema will still be cached (arguably a bug or missing feature). You can reload User's schema cache with User.reload_schema_from_cache or possibly connection.schema_cache.clear_data_source_cache(Users.table_name.
I guess it's a cache thing. I couldn't tell if a bug or not, I don't have much knowledge of rails internals but I gues it's that way by design. It's not even a common use case to create tables from within the console.
You could skip the exit > enter steps calling reload! on the console to reload everything though.

Cannot delete record from rails console in AWS eb cli if a wrong subclass value is specified for a STI parent class

A colleague added a new record for the class "Production" via our rails admin interface, which is the parent class via STI of the subclass "CoProduction".
The type attribute was by mistake filled out via the rails_admin with a value that is not the specified subclass "CoProduction", but with a wrong one. As a result I cannot delete nor update the record from rails console in our AWS environment (and the rails admin interface has crashed and is not starting over again either).
[1] pry(main)> Production.last
Production Load (1.0ms) SELECT "productions".* FROM "productions" ORDER BY "productions"."id" DESC LIMIT $1 [["LIMIT", 1]]
ActiveRecord::SubclassNotFound: The single-table inheritance mechanism
failed to locate the subclass: 'opera buffa'. This error is raised
because the column 'type' is reserved for storing the class in case of
inheritance. Please rename this column if you didn't intend it to be
used for storing the inheritance class or overwrite
Production.inheritance_column to use another column for that
information.
EDIT
I could solve the issue meanwhile, by connecting via PGADMIN to the db instance,retrieving the culprit record and modify it. Unfortunately this error was not to be solved in an ActiveRecord environment
It seems that the record was somehow added by skipping the default validation defined for STI. You can follow the same way to recover the record and set its proper type by using:
ActiveRecord::Relation#update_all, which neither instantiates the involved models nor triggers Active Record callbacks/validations.
In rails console, find all occurrences of wrong types (e.g. opera buffa) in Production model and update it to type CoProduction:
Production.where(type: 'opera buffa').update_all(type: 'CoProduction')
Production model should work as usual after this point.
I could solve the issue meanwhile, by connecting via PGADMIN to the db instance,retrieving the culprit record and modify it. Unfortunately this error was not to be solved in an ActiveRecord environment

How I can see all the queries executed and classes or methods in my gemfile?

I´m newbie in RoR and I would like to know how I can do two things in Rails (both versions 2 and 3):
How I can see all queries generated to database (save, update, find, etc.) in the console of the server?
How I can see all the classes and methods of gems included in my Gemfile?
For example how I can see classes and methods of CanCan, Devise and so on.
gem "devise"
gem "cancan"
gem "rolify"
gem "sass-rails"
And so on...
Sorry for my english and thank in advance!!
In your rails folder there will be a log sub-folder. Depending on where your application is running and on your configurations you'll be able to see something similar to a development.log, staging.log or production.log file in that folder.
Also the .to_sql method can be used to show the sql. e.g.
User.where(:id => 29).to_sql will yield the following:
"SELECT `users`.* FROM `users` WHERE `users`.`id` = 29"
For viewing gems. In terminal type bundle show devise this will return you a path. Go to that path. All the necessary code will be present over there.
/home/sohaib/.rvm/gems/ree-1.8.7-2011.03#moviepass/gems/devise-1.4.9

Resources