I have an trackers table and applications tables
application.rb
has_many :trackers
tracker.rb
belongs_to :application
What I trying to do is update the check_in_date in the trackers table to be query to begin_date in the applications tables only for those records which have check_in_date is equal to "2019-05-30".
I am trying to run the command below but I am getting an error.
Tracker.joins(:application).where("check_in_date = ?", "2019-05-30").update_all("tracker.check_in_date = application.begin_date")
error
ActiveRecord::StatementInvalid (PG::UndefinedTable: ERROR: missing FROM-clause entry for table "application")
Any idea where i am going wrong.
Maybe try this:
Note I have no idea if this will work so don't do it in production unless you can confirm
Tracker.where(check_in_date: "2019-05-30")
.update_all("check_in_date = (#{
Application.select(:begin_date)
.where('applications.id = trackers.application_id').to_sql})"
)
The theory is that this should result in the following SQL
UPDATE trackers
SET check_in_date = (
SELECT
begin_date
FROM
applications
WHERE
applications.id = trackers.application_id
)
WHERE
trackers.check_in_date = "2019-05-30"
There seems some typo
if check_in_date is date type then convert is "2019-05-30" in date
my_check_in_date = "2019-05-30".to_date
While using any attribute in the query model name should always be plural
Tracker.joins(:application)
.where("trackers.check_in_date= ?", my_check_in_date)
.update_all("trackers.check_in_date = applications.begin_date")
.references(:application)
Related
I have two Postgres tables that look like above.
amount_availables belongs to facilities as shown below:
class AmountAvailable < ApplicationRecord
belongs_to :sequence_number
belongs_to :facility
validates :facility, :presence => true
When I run a complex query that joins these 2 tables, I get the below error (and this error is not consistent):
ActiveModel::MissingAttributeError (missing attribute: facility_id):
Generated SQL:
This is the SQL that's generated:
SELECT "as_of_date", "entity", "facility", "financial_institution", "amount_availables"."amount_available", "amount_availables"."comments", "amount_availables"."last_updated_on", "amount_availables"."last_updated_by" FROM "amount_availables" INNER JOIN "sequence_numbers" ON "sequence_numbers"."sequence_number" = "amount_availables"."sequence_number_id" INNER JOIN "facilities" ON "facilities"."facility_id" = "amount_availables"."facility_id" WHERE (sequence_numbers.as_of_date >= '10/01/2019' and sequence_numbers.as_of_date <= '12/24/2019' AND facilities.entity in ('3C7','HOLD CO','PCM','PC-M','PFSI','PLS','PMIT','POP','QRS','TAG','TRS')) ORDER BY last_updated_on desc
NOTE:
And until last week, I remember I was getting this error inconsistently (it occurred a LOT of times but not ALL the time! But this week I seem to get it pretty much all the time. And this SQL runs just fine on Postgres client against the same database that my Rails app is using).
Does this error mean there should be a column named facility_id in facilities table?
What should I do on my Rails code to fix this?
I even tried renaming the id column in facilities table to facility_id using the Rails migration code below:
Approach 1 - Rails Migration Fix
class ModifyFacilitiesPkColumnName < ActiveRecord::Migration
def change
rename_column :facilities, :id, :facility_id
end
end
But I am still getting the same error even after the above approach (I DID run rake db:migrate and I can see in my postgres client that the id column in facilites HAS changed to facility_id).
What does this error mean precisely, and how do I fix this?
Your Inner Join seems to be incorrect:
SELECT * FROM "amount_availables"
INNER JOIN "sequence_numbers" ON "sequence_numbers"."sequence_number" = "amount_availables"."sequence_number_id"
INNER JOIN "facilities" ON "facilities"."facility_id" = "amount_availables"."facility_id"
WHERE (sequence_numbers.as_of_date >= '10/01/2019' and sequence_numbers.as_of_date <= '12/24/2019' AND facilities.entity in ('3C7','HOLD CO','PCM','PC-M','PFSI','PLS','PMIT','POP','QRS','TAG','TRS')) ORDER BY last_updated_on desc
Instead it should be:
INNER JOIN "facilities" ON "facilities"."id" = "amount_availables"."facility_id"
It should work.
How do you query on Ruby on Rails or translate this query on Ruby on Rails?
SELECT
orders.item_total,
orders.total,
payments.created_at,
payments.updated_at
FROM
public.payments,
public.orders,
public.line_items,
public.variants
WHERE
payments.order_id = orders.id AND
orders.id = line_items.order_id AND
This is working on Postgres but I'm new to RoR and it's giving me difficulty on querying this sample.
So far this is what I have.
Order.joins(:payments,:line_items,:variants).where(payments:{order_id: [Order.ids]}, orders:{id:LineItem.orders_id}).distinct.pluck(:email, :id, "payments.created_at", "payments.updated_at")
I have a lot of reference before asking a question here are the links.
How to combine two conditions in a where clause?
Rails PG::UndefinedTable: ERROR: missing FROM-clause entry for table
Rails ActiveRecord: Pluck from multiple tables with same column name
ActiveRecord find and only return selected columns
https://guides.rubyonrails.org/v5.2/active_record_querying.html
from all that link I produced this code that works for testing.
Spree::Order.joins(:payments,:line_items,:variants).where(id: [Spree::Payment.ids]).distinct.pluck(:email, :id)
but when I try to have multiple queries and pluck a specific column name from a different table it gives me an error.
Update
So I'm using Ransack to query I produced this code.
#search = Spree::Order.ransack(
orders_gt: params[:q][:created_at_gt],
orders_lt: params[:q][:created_at_lt],
payments_order_id_in: [Spree::Order.ids],
payments_state_eq: 'completed',
orders_id_in: [Spree::LineItem.all.pluck(:order_id)],
variants_id_in: [Spree::LineItem.ids]
)
#payment_report = #search.result
.includes(:payments, :line_items, :variants)
.joins(:line_items, :payments, :variants).select('payments.response_code, orders.number, payments.number')
I don't have error when I remove the select part and I need to get that specific column. Is there a way?
You just have to make a join between the tables and then select the columns you want
Spree::Order.joins(:payments, :line_items).pluck("spree_orders.total, spree_orders.item_total, spree_payments.created_at, spree_payments.updated_at")
or
Spree::Order.joins(:payments, :line_items).select("spree_orders.total, spree_orders.item_total, spree_payments.created_at, spree_payments.updated_at")
That is equivalent to this query
SELECT spree_orders.total,
spree_orders.item_total,
spree_payments.created_at,
spree_payments.updated_at
FROM "spree_orders"
LEFT OUTER JOIN "spree_payments" ON "spree_payments"."order_id" = "spree_orders"."id"
LEFT OUTER JOIN "spree_line_items" ON "spree_line_items"."order_id" = "spree_orders"."id"
You can use select_all method.This method will return an instance of ActiveRecord::Result class and calling to_hash on this object would return you an array of hashes where each hash indicates a record.
Order.connection.select_all("SELECT
orders.item_total,
orders.total,
payments.created_at,
payments.updated_at
FROM
public.payments,
public.orders,
public.line_items,
public.variants
WHERE
payments.order_id = orders.id AND
orders.id = line_items.order_id").to_hash
In rails 5 with Postgresql, I'm writing a scope to select Status items by date. My model is:
class Status < ApplicationRecord
scope :in_month, ->(date){where("status_date = ?", date) if date.present?}
end
However, in rails console, I'm getting the following error when trying to use the scope.
```
2.4.0 :010 > Status.in_month("2018-06-01")
Status Load (11.7ms) SELECT "statuses".* FROM "statuses" WHERE (status.status_date = '2018-06-01') LIMIT $1 [["LIMIT", 11]]
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: missing FROM-clause entry for table "status"
LINE 1: SELECT "statuses".* FROM "statuses" WHERE (status.status_da...
^
: SELECT "statuses".* FROM "statuses" WHERE (status.status_date = '2018-06-01') LIMIT $1
Note that for some reason, it's trying to access table "status", not "statuses".
What the heck am I doing wrong? This is pretty much straight out of the RailsGuide.
EDIT & "fix"
Humph... apparently the Rails console was in a bad state. I restarted the console after the comments below and found that my query worked perfectly. Note that the quotes are required for this format of the WHERE clause and that statuses is a correct pluralization of status.
And after restarting, the where(status_date: date) format described by praga2050 worked, as did the where("statuses.status_date = ?", date) suggested by Kedarnag Mukanahallipatna.
Lesson learned: reload! doesn't reload changes in models; you have to restart the console for Model changes to be recognized. See this SO answer: https://stackoverflow.com/a/5428421/446464
I think you missed the point of naming conventions in rails.
Model class names are singular, and will map automatically to the plural database table name.
According to this, you can change your model name to statuses.
Or set a table name to use in the rails model:
class Status < ApplicationRecord
self.table_name = 'status'
scope :in_month, ->(date) { where(status_date: date) if date.present? }
end
I am not sure why you are putting string inside the Where clause
scope :in_month, ->(date){where("status_date = ?", date) if date.present?}
Should be change like below.
Below one should work for you.
scope :in_month, ->(date){where(status_date: date) if date.present?}
I have this rake task to import a csv file that I'm trying to debug, with a similar pattern to create records in 8 different tables from each row in the file. Records in the independent tables get created, then I need to find those records' id numbers to use as foreign keys to create records in the dependent tables.
The error says:
rake aborted!
ActiveRecord::StatementInvalid: Mysql2::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 'BLANCO) LIMIT 1' at line 1: SELECT `fields`.* FROM `fields` WHERE (IGNACIO BLANCO) LIMIT 1
which I verified in the MySQL console. But in the previous five tables, this similar code works fine to obtain the foreign keys:
require 'csv'
CSV.foreach('public/partial.csv', :headers => true) do |row|
# create the Company object
this_company_name = row['name'].strip!
this_operator_num = row['operator_num']
if !(Companies.exists?(:company_name => this_company_name))
Companies.create(company_name: this_company_name, operator_num: this_operator_num)
end
thecompany = Companies.find_by(company_name: this_company_name)
company_id = thecompany.id
# create the County object
this_county_name = row['county'].strip!
if !(Counties.exists?(county_name: this_county_name))
Counties.create(county_name: this_county_name)
end
thecounty = Counties.find_by(county_name: this_county_name)
county_id = thecounty.id
# create the Gastype object
this_gastype_name = row['gas_type'].strip!
if !(Gastypes.exists?(gas_type: this_gastype_name))
Gastypes.create(gas_type: this_gastype_name)
end
thegastype = Gastypes.find_by(gas_type: this_gastype_name)
gastype_id = thegastype.id
# create the Field object
this_field_name = row['field_name'].strip!
this_field_code = row['field_code'].strip!
if !(Fields.exists?(field_name: this_field_name))
Fields.create(field_name: this_field_name, field_code: this_field_code)
end
thisfield = Fields.find_by(this_field_name)
field_id = thisfield.id
...
The SQL statement that Rails created which produces the error is:
SELECT `fields`.* FROM `fields` WHERE (IGNACIO BLANCO) LIMIT 1;
which has an obviously incorrect WHERE clause. My question is why did Rails not produce the correct statement, like:
SELECT fields.* FROM fields WHERE (field_name ='IGNACIO BLANCO') LIMIT 1;
Should I change how the .find_by statement is written? Or is there a better way of obtaining the requisite foreign key?
Because of this line:
thisfield = Fields.find_by(this_field_name)
You're simply passing a string to find_by, and Rails will consider it to be raw SQL.
You need to use either of these two solutions:
thisfield = Fields.find_by_field_name(this_field_name)
thisfield = Fields.find_by(field_name: this_field_name)
I need to dump a set of Awards into a instance variable:
#corp = Award.find(:all, :conditions => ["award.category_id = ?", "2" ])
Award <= => AwardsCategories <= => Categories
I am trying to find All the Awards that have a Category of X
The interesting piece I am noticing is that my Award.category_id is nil but the AwardsCategory.category_id and award_id are both set.
The error is returning is:
ActiveRecord::StatementInvalid in PagesController#award_cat
PGError: ERROR: missing FROM-clause entry for table "award"
LINE 1: SELECT "awards".* FROM "awards" WHERE (award.category_id = ...
^
: SELECT "awards".* FROM "awards" WHERE (award.category_id = '2')
Any ideas and merry christmas
With a habm award doesn't need a category_id (after all, if it was used, how could an award have multiple categories?)
You need to join the award_categories table and put conditions on award_categories.category_id. Obviously if you have an actual category handy, you can just do
category.awards