ruby on rails: search through associations - ruby-on-rails

I have little understanding problem:
I have Channel and Lecturer, where a Channel :has_and_belongs_to_many :lecturers.
I want to get all Channels where Lecturer.id is lect.id.
2.3.0 :235 > Channel.where(:lecturers => { :id => 2 })
Channel Load (0.1ms) SELECT "channels".* FROM "channels" WHERE "lecturers"."id" = 2
SQLite3::SQLException: no such column: lecturers.id: SELECT "channels".* FROM "channels" WHERE "lecturers"."id" = 2
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: lecturers.id: SELECT "channels".* FROM "channels" WHERE "lecturers"."id" = 2
This does not work and I feel like I don't understand the core concept, since I can do
2.3.0 :231 > Channel.first.lecturer
=> #<Lecturer id: 2, name: "Albert Einstein">
What am I missing?

You'll want to join the tables to do this query. See the docs
Channel.joins(:lecturer).where(lecturers: {id: lect.id})

Related

How to properly make a Raw SQL in Ruby on Rails?

I am into a Rails Console session trying to run a Raw SQL query. If I use Active Record like this, this is the result:
irb(main):006:0> count = Sf::Program.count
Sf::Program Count (132.8ms) SELECT COUNT(*) FROM "salesforce"."program__c"
=> 54348
If I try to run this same query, but with ActiveRecord
irb(main):007:0> sql = 'SELECT COUNT(*) FROM salesforce.program__c'
=> "SELECT COUNT(*) FROM salesforce.program__c"
irb(main):008:0> sql = 'SELECT COUNT(*) FROM "salesforce"."program__c"'
=> "SELECT COUNT(*) FROM \"salesforce\".\"program__c\""
irb(main):009:0> ActiveRecord::Base.connection.exec_query(sql)
IM getting an error
/Volumes/Laje/fmaymone/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/activerecord-7.0.4/lib/active_record/connection_adapters/postgresql_adapter.rb:768:in `exec_params': ERROR: relation "salesforce.program__c" does not exist (PG::UndefinedTable)
LINE 1: SELECT COUNT(*) FROM "salesforce"."program__c"
What IM doing wrong here???

Active Record calculations in Ruby

Could someone please help on how to use 'where' condition in this active record condition or why this throws error in rails 4.2?
p = Project.first
Project Load (34.6ms) SELECT `projects`.* FROM `projects` ORDER BY `projects`.`id` ASC LIMIT 1
=> #<Project id: 1, name: "First Project", created_at: "2015-12-29 16:27:42", updated_at: "2015-12-29 16:27:42">
2.2.1 :031 > p.tasks.sum(:priority)
(26.8ms) SELECT SUM(`tasks`.`priority`) FROM `tasks` WHERE `tasks`.`project_id` = 1
=> 9
2.2.1 :032 > p.tasks.sum(:priority).where(:complete => 0)
(0.2ms) SELECT SUM(`tasks`.`priority`) FROM `tasks` WHERE `tasks`.`project_id` = 1
**NoMethodError: undefined method `where' for 9:Fixnum**
sum returns Fixnum, not AR relation. You need to reverse where and sum order:
p.tasks.where(:complete => 0).sum(:priority)

Active Record "Where" Query Failing to find Record

So have a token model that has keys which are strings. I am doing a search for a token that exists and when i do a direct comparrison of the string with the record it should find i get an empty active record relation object.
Anyone know what is going on here? Am i stepping on a models toes by using the Model name 'Token'. I didn't find anything in the googles about it.
I've stored the key as 'a' below and Token.last.key is the database entry that has the matching key.
irb(main):023:0> a
=> "279684d7488254c41bb4039ad0962007"
irb(main):024:0> Token.last.key
Token Load (0.4ms) SELECT "tokens".* FROM "tokens" ORDER BY "tokens"."id" DESC LIMIT 1
=> "279684d7488254c41bb4039ad0962007"
irb(main):025:0> a == Token.last.key
Token Load (0.1ms) SELECT "tokens".* FROM "tokens" ORDER BY "tokens"."id" DESC LIMIT 1
=> true
irb(main):026:0> Token.where(key: a)
Token Load (0.2ms) SELECT "tokens".* FROM "tokens" WHERE "tokens"."key" = '279684d7488254c41bb4039ad0962007'
=> #<ActiveRecord::Relation []>
irb(main):027:0> Token.where(key: a.to_s)
Token Load (0.2ms) SELECT "tokens".* FROM "tokens" WHERE "tokens"."key" = '279684d7488254c41bb4039ad0962007'
=> #<ActiveRecord::Relation []>
Oddly enough, when i do a search through all the records i do return the correct user
#DOES WORK
def current_user(key)
Token.all.first {|t| return t.key == key }
end
What i have will work but what i would like it to do this in the database with something like this
#DOES NOT WORK
def current_user(key)
Token.where(key: key).try(:user)
end
Doing search based on suggestion below returning nil for find_by
irb(main):004:0> a = Token.last.key
Token Load (0.2ms) SELECT "tokens".* FROM "tokens" ORDER BY "tokens"."id" DESC LIMIT 1
=> "279684d7488254c41bb4039ad0962007"
irb(main):005:0> Token.find_by(key: a)
Token Load (0.2ms) SELECT "tokens".* FROM "tokens" WHERE "tokens"."key" = '279684d7488254c41bb4039ad0962007' LIMIT 1
=> nil
Solution was to do this
def find_user_by_api(key)
tokens = Token.arel_table
Token.where(tokens[:key].matches(key)).try(:first).try(:user)
end
Wish it helps
Token.find_by(key: a)

Friendly_id-globalize 'find() through' association isn't using translation table

In Rails 4:
Using find() directly on my model generates a query which looks up the slug in the page_translations table:
Page.find('my-title')
SELECT FROM "pages" LEFT OUTER JOIN "page_translations" ...
-> #<Page id: 1 ...>
When I use find through a association, the translation table isn't being used. friendly_id uses the orginal table instead.
#site.pages.find('my-title')
SELECT "pages".* FROM "pages" WHERE "pages"."site_id" = $1 AND "pages"."slug" = 'my-title' LIMIT 1 [["site_id", 1]]
-> ActiveRecord::RecordNotFound
In Rails 3.2 (friendly_id 4.0.10, globalize 3.0.0) it works like this:
#site.pages.find('my-title')
SELECT "pages".* FROM "pages" WHERE "pages"."shop_id" = 1 AND "pages"."slug" = 'my-title' LIMIT 1
SELECT DISTINCT "pages".id, pages.position AS alias_0 FROM "pages" LEFT OUTER JOIN "page_translations" ...
SELECT "pages"."id" AS t0_r0, "pages"."title" AS t0_r1 ... FROM "pages" LEFT OUTER JOIN "page_translations"
-> #<Page id: 1 ...>
See also https://github.com/norman/friendly_id-globalize/issues/1.
Repo owner #parndt is currently busy. So any hints to get this gem working will be greatly appreciated.
Turned out to be a bug in the Globalize gem, which has been fixed shortly.

Rails uniqueness => true encoding issue

Ive run into an issue with rails uniqueness validator when using UTF character in rails 3.0.12 (Ruby 1.8.7).
Here's my little test:
CORRECT:
name = "dave"
count = User.where(:name => name).count
u = User.new(:name => name, :gender => "Male")
puts "Current: #{count} / Valid: #{u.valid?} / Errors: #{u.errors.to_a.to_sentence}"
Output: Current: 1 / Valid: false / Errors: Name is already taken
SQL (0.2ms) SELECT COUNT(*) FROM `users` WHERE `users`.`name` = 'dave'
SQL (0.1ms) SELECT 1 FROM `users` WHERE (`users`.`name` = BINARY 'dave') LIMIT 1
INCORRECT:
name = "angélique"
count = User.where(:name => name).count
u = User.new(:name => name, :gender => "Male")
puts "Current: #{count} / Valid: #{u.valid?} / Errors: #{u.errors.to_a.to_sentence}"
Output: Current: 3 / Valid: true / Errors:
SQL (0.1ms) SELECT COUNT(*) FROM `users` WHERE `users`.`name` = 'angélique'
SQL (0.1ms) SELECT 1 FROM `users` WHERE (`users`.`name` = BINARY 'angélique') LIMIT 1
It seems the where clause uses the correct encoding and finds the result but the check on the presence validator doesn't.
Any ideas how i could resolve this?
I think it's likely that your app is using UTF-8 but that your DB isn't:
http://guides.rubyonrails.org/getting_started.html#configuration-gotchas
That guide contains examples for doing this for MySQL and PostgreSQL earlier in the page.

Resources