I make select
m_repeats = Event.where(:repeat => 'monthly').where("schedule < ?", date.end_of_month)
Then I need change the shedule (it is date field) in each element.
I try to do:
m_repeats.map{ |elem| elem.schedule.year = date.today.year, elem.schedule.month = date.today.month }
But I get the errors:
Mysql2::Error: Unknown column 'schedule' in 'where clause': SELECT `events`.* FROM `events` WHERE `events`.`repeat` = 'monthly' AND (schedule < '2013-04-30')
or
undefined method `schedule' for #
What is correct way to do it?
Try to use only one where statement like
m_repeats = Event.where('events.repeat = ? AND events.schedule < ?', 'monthly', date.end_of_month)
or explicitly name the table of your query on the schedule column like
m_repeats = Event.where(:repeat => 'monthly').where("events.schedule < ?", date.end_of_month)
I don't think that your map method is causing the problem, because the select of the Events takes place at the call of the map method and there you get a clear problem in your select query.
it was really grammar error :) 'schedule' instead of 'shedule'
Related
I receive an error of
Mysql2::Error: Unknown column 'requests.access_level_id' in 'where clause':
SELECT `requests`.*
FROM `requests` LEFT OUTER JOIN `users` ON `users`.`id` = `requests`.`from_id`
WHERE `requests`.`access_level_id` = 1
ORDER BY id DESC
Model
class Request < ApplicationRecord
belongs_to :user, foreign_key: :from_id
end
Controller
#req = Request.left_outer_joins(:user).where(access_level_id: 1).order('id DESC')
How can I remove requests from the WHERE clause requests.access_level_id = 1? I just want access_level_id = 1 to be in the where statement.
As you requested, you can add where clause without requests as,
#req = Request.left_outer_joins(:user).where('access_level_id = ?', 1).order('id DESC')
But its good to keep relative aliasing for access_level_id. If its users then please use it like,
#req = Request.left_outer_joins(:user).where(users: { access_level_id: 1 }).order('id DESC')
Assuming that access_level_id is field for user, you can replace your query with following:
#req = Request.left_outer_joins(:user).where('users.access_level_id = ?', 1).order('id DESC')
By default the fields in where conditions are considered to be belonging to Request method in your query.
Hope this helps you.
Please let me know if you face any issue.
I have a meetings table, which has a requestor (user) with an attribute birthyear.
In the terminal I can do Meeting.find(1).requestor.birthyear
But in the meeting controller, it says no such column: requestor.birthyear
I tried adding something like users_attributes: [:birthyear] in the meetings_params, but it didn't make any difference.
What am I missing?
Here are the full files:
meeting controller
def community
if current_user.birthyear != nil
#meeting_requests = Meeting.where('meeting_time >= ? AND requestee_id IS ? AND status = ? AND (requestor.birthyear <= ? AND requestor.birthyear >= ?)', Date.today, nil, "Active", current_user.birthyear + 10, current_user.birthyear - 10).order('meeting_time asc')
end
end
meeting model
class Meeting < ApplicationRecord
belongs_to :requestor, class_name: "User"
belongs_to :requestee, class_name: "User"
end
error:
SQLite3::SQLException: no such column: requestor.birthyear: SELECT "meetings".* FROM "meetings" WHERE (meeting_time >= '2017-03-06' AND requestee_id IS NULL AND status = 'Active' AND (requestor.birthyear <= 1944 AND requestor.birthyear >= 1924)) ORDER BY meeting_time asc
Let me know if you need anything further - thank in advance!
UPDATE
trying to join the tables in the query, but not too knowledgeable on that. I'm trying:
#meeting_requests = Meeting.where('meeting_time >= ? AND requestee_id IS ? AND status = ? ', Date.today, nil, "Active").order('meeting_time asc').joins("INNER JOIN users on requestor.birthyear >= current_user.birthyear + 10")
but get:
ActionView::Template::Error (SQLite3::SQLException: ambiguous column name: status: SELECT "meetings".* FROM "meetings" INNER JOIN users on requestor.birthyear >= current_user.birthyear + 10 WHERE (meeting_time >= '2017-03-07' AND requestee_id IS NULL AND status = 'Active' ) ORDER BY meeting_time asc):
*****UPDATE*****
I posted another question to get the syntax. If it helps anyone:
Rails: Two 'where' queries - each works individually, but not together
requestor and requestee are Rails associations. This means that Rails understands how to get to requestor from a Meeting...
However - your database does not know what a requestor is. So you can't put it into the string-part of a SQL-query like you have done here:
AND (requestor.birthyear <= ? AND requestor.birthyear >= ?)'
Instead you will need to use joins to add these to your query, then figure out how rails names them in order to access the columns from them.
I am trying to find the best way to include a referenced model on what is essentially a compound key.
I have ChecklistItem (a list of things to do daily) and then ChecklistChecks (which ties the ChecklistItem together with a User for a particular day. These checklists can either be for all Stores (with a null store_id) or for a particular Store.
This pulls all of the ChecklistItems and their associated checks:
ChecklistItem.includes(:checklist_checks).where(store_id: [nil,#store.id], list_type: 'open')
The problem is that there would be checks from multiple days in there. What I need is to pull all of the ChecklistItems and any checks from a specific day.
I tried adding conditions like this:
ChecklistItem.includes(:checklist_checks).where(store_id: [nil,#store.id], list_type: 'open', checklist_checks: {store_id: #store.id, report_date: #today})
The problem is that will only pull ChecklistItems that have an associated ChecklistCheck.
It is generating SQL that is essentially:
SELECT
checklist_items.*,
checklist_checks.*
FROM
checklist_items
LEFT OUTER JOIN
checklist_checks
ON
checklist_checks.checklist_item_id = checklist_items.id
WHERE
checklist_items.list_type = 'open'
AND
checklist_checks.store_id = 1
AND
checklist_checks.report_date = '2015-05-03'
AND
(checklist_items.store_id = 1 OR checklist_items.store_id IS NULL)
I think the problem is that the conditions on checklist_checks is in the WHERE clause. If I could move them to the ON clause of the join, everything would work.
Is there a Rails way to end up with something like this?
SELECT
checklist_items.*,
checklist_checks.*
FROM
checklist_items
LEFT OUTER JOIN
checklist_checks
ON
checklist_checks.checklist_item_id = checklist_items.id
AND
checklist_checks.store_id = 1
AND
checklist_checks.report_date = '2015-05-03'
WHERE
checklist_items.list_type = 'open'
AND
(checklist_items.store_id = 1 OR checklist_items.store_id IS NULL)
UPDATE:
I found this: enter link description here
It suggests using find_by_sql and then passing the result array and model to be included to ActiveRecord::Associations::Preloader.new.preload
I tried that, and my find_by_sql pulls the right stuff, but the id column is nil in the resulting objects.
#store = Store.find(1)
#today = Date.today - 1.days
#open_items = ChecklistItem.find_by_sql(["SELECT checklist_items.*, checklist_checks.* FROM checklist_items LEFT OUTER JOIN checklist_checks ON checklist_checks.checklist_item_id = checklist_items.id AND checklist_checks.store_id = ? AND checklist_checks.report_date = ? WHERE checklist_items.list_type='open' AND (checklist_items.store_id=? OR checklist_items.store_ID IS NULL)", #store.id, #today, #store_id])
ActiveRecord::Associations::Preloader.new.preload(#open_items, :checklist_checks)
> #open_items.first.name
=> "Turn on the lights"
> #open_items.first.id
=> nil
A solution using Arel to generate a custom join clause:
class ChecklistItem < ActiveRecord::Base
has_many :checklist_checks
# ...
def self.superjoin(date, store_id)
# build the ON clause for the join
on = Arel::Nodes::On.new(
Arel::Nodes::Equality.new(ChecklistChecks.arel_table[:checklist_item_id], ChecklistItem.arel_table[:id]).\
and(ChecklistItem.arel_table[:store_id].eq(1)).\
and(ChecklistChecks.arel_table[:report_date].eq(date))
)
joins(Arel::Nodes::OuterJoin.new(ChecklistChecks.arel_table, on))
.where(store_id: [nil, store_id], list_type: 'open' )
end
end
I bundled it up into a model method to make it easier to test in the rails console.
irb(main):117:0> ChecklistItem.superjoin(1,2)
ChecklistItem Load (0.5ms) SELECT "checklist_items".* FROM "checklist_items" LEFT OUTER JOIN "checklist_checks" ON "checklist_checks"."checklist_item_id" = "checklist_items"."id" AND "checklist_items"."store_id" = 1 AND "checklist_checks"."report_date" = 1 WHERE (("checklist_items"."store_id" = 2 OR "checklist_items"."store_id" IS NULL)) AND "checklist_items"."list_type" = 'open'
=> #<ActiveRecord::Relation []>
I am working with the RailsCast on token input and am trying to cleanup a query method for Postgres. I found this post for making my query DB-agnostic.
My method:
def self.tokens(query)
t = Language.arel_table
languages = Language.where(t[:name].matches("%#{query}%"))
if languages.empty?
[{id: "<<<#{query}>>>", name: "New: \"#{query}\""}]
end
end
Returns
:001 > Language.tokens('Ru')
(0.8ms) SELECT COUNT(*) FROM "languages" WHERE ("languages"."name" ILIKE '%Ru%')
But if I use return instead of language =, I get the correct query:
def self.tokens(query)
t = .arel_table
return Language.where(t[:name].matches("%#{query}%"))
end
:001 > Language.tokens('Ru')
Language Load (0.9ms) SELECT "languages".* FROM "languages" WHERE ("languages"."name" ILIKE '%Ru%')
It's probably something obvious, but I cannot figure out why the first method is selecting count instead of all of the rows in the `languages' table db. I would really like to store the result of that query in a variable.
It's because the where is resolved as lazily as it possibly can be (not until it is absolutely needed). In your case it needs it when you:
Explicitly return
Check empty?
The reason it is doing the count, is to determine via the count whether it is empty.
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