I have a table with 2 foreign key relationships - to a Timeline and a Phase. When I create a record in my development database it all works 100% as expected, but when I do it in test mode it refuses to add the Timeline - you can see from the INSERT statement that it flatly refuses .. it doesn't even try to add it. When I run the exact same sequence below in development it's fine
I can add/update timeline_id but then it doesn't reference the timeline through the parent phase_timeline object as it should. I repeat that this all works fine in development, but not in test. Its driving me mad. Is it failing a validation possibly.. or could the database be corrupt. Are there some console commands I could run to check out the foreign key relationship further?
[33] pry(main)> t = Timeline.last
Timeline Load (0.3ms) SELECT "timelines".* FROM "timelines" ORDER BY "timelines"."id" DESC LIMIT $1 [["LIMIT", 1]]
=> #<Timeline:0x0055fd716dcfa8 id: 1, title: "England", timelineable_type: "Global", timelineable_id: 1, created_at: Thu, 24 Sep 2020 14:46:28 UTC +00:00, updated_at: Thu, 24 Sep 2020 14:46:28 UTC +00:00>
[34] pry(main)> p = Phase.last
Phase Load (1.3ms) SELECT "phases".* FROM "phases" WHERE "phases"."deleted_at" IS NULL ORDER BY "phases"."id" DESC LIMIT $1 [["LIMIT", 1]]
=> #<Phase:0x0055fd717f8450
id: 1,
name: "First phase",
development_id: 1,
created_at: Thu, 24 Sep 2020 14:46:28 UTC +00:00,
updated_at: Thu, 24 Sep 2020 14:46:28 UTC +00:00,
developer_id: 1,
division_id: 1,
number: 1,
deleted_at: nil,
total_snags: 0,
unresolved_snags: 0,
business: "core">
[35] pry(main)> pt = PhaseTimeline.create(phase: p, timeline: t)
(0.2ms) BEGIN
SQL (0.5ms) **INSERT INTO "phase_timelines" ("phase_id") VALUES ($1) RETURNING "id" [["phase_id", 1]]**
(1.8ms) COMMIT
=> #<PhaseTimeline:0x0055fd719ef9c0 id: 5, phase_id: 1, timeline_id: nil>
After a LOT of head scratching and diving into the bowels .. this problem was caused by having 2 model classes with the same name. The classes were in 2 separate folder but had the same scope and were identical but removing the errant one sorted the problem
Related
I am working on a Ruby on Rails project and I have several tasks with this structure in a Postgresql database :
id: 8,
name: "Task 1",
due_date: Mon, 25 Jul 2022,
finished: true,
reviewed: false,
note: nil,
tags: [{"id"=>6, "name"=>"tag_1"}, {"id"=>7, "name"=>"tag_2"}],
assigned_to: [{"id"=>7, "username"=>"Julia"}, {"id"=>8, "username"=>"Joe"}],
user_id: 5,
group_id: 4,
created_at: Sat, 06 Aug 2022 01:09:31.135203000 UTC +00:00,
updated_at: Sat, 06 Aug 2022 01:09:31.135203000 UTC +00:00,
pending: false>
And I want to query those tags depending on the the tag id and the assigned_to id.
The column types are:
t.jsonb "tags", default: [], array: true
t.jsonb "assigned_to", default: [], array: true
I checked this source: Query on Postgres JSON array field in Rails
but couldn't figure out how it works, this is what I get:
Task.where("tags::jsonb #> ?", [{"id": 6}, {"id": 7}].to_json)
Task Load (3.8ms) SELECT "tasks".* FROM "tasks" WHERE (tags::jsonb #> '[{"id":6},{"id":7}]')
Task Load (0.9ms) SELECT "tasks".* FROM "tasks" WHERE (tags::jsonb #> '[{"id":6},{"id":7}]') /* loading for inspect */ LIMIT $1 [["LIMIT", 11]]
=> #<Task::ActiveRecord_Relation:0x4290>
Is there a way to query it? Thanks!
You could use JSONB_TO_RECORDSET to extract tasks.tags->'id' and the same way tasks.assigned_to->'id' and have a couple of extra columns you can use for the filtering:
Task
.from('tasks, JSONB_TO_RECORDSET(tasks.tags) AS tags(id int), JSONB_TO_RECORDSET(tasks.tags) AS assigned_to(id int)')
.where('tags.id = ? AND assigned_to.id = ?', 6, 7)
# SELECT "tasks".* FROM JSONB_TO_RECORDSET(tasks.tags) AS tags(id int), JSONB_TO_RECORDSET(tasks.tags) AS assigned_to(id int) WHERE (tags.id = 6 AND assigned_to.id = 7)
Notice the Active Record where won't work using hashes (like where(tags: { id: 6, ... }) as one might intuitively think), so the binding has to be done manually.
Notice this works by using tags and assiged_to as jsonb not jsonb[] as it's in your example. So you might have to remove the array: true argument in your migration.
This question already has answers here:
Case-insensitive search in Rails model
(21 answers)
Closed 3 years ago.
I have these two tables:
product has_one address
address belongs_to product
When I want to find a product from one city, I do:
Product.all.joins(:address).where(addresses: {city: #city})
When I want to to find all cities with case insensitive is
Address.all.where('lower(city) like ?', #city.downcase)
But now I want a record from another table with case insensitive combined. How can I do ?
I tried some ways and nothing:
Product.all.joins(:address).where(addresses: {"lower(city) like ?", #city.downcase})
gives the error:
SyntaxError: unexpected '}', expecting end-of-input
...ower(city) like ?", "new york"})
...
and the other way:
Product.all.joins(:address).where(addresses: {"lower(city) like ?": #city.downcase})
gives nothing:
#<Product::ActiveRecord_Relation:0x3fb3fc142900>
Obs: I created another question because the old one was wrongly marked as duplicated.
Product.joins(:address).where "lower(addresses.city) like ?", #city.downcase
Response to comment
No idea what you're talking about "didn't track from the column city on addresses table" - what does "didn't track" mean?
Here's a console session with your models as described showing my code above working just as described:
[14] pry(main)> Address.create city: "New York", product: Product.first
Product Load (0.3ms) SELECT "products".* FROM "products" ORDER BY "products"."id" ASC LIMIT $1 [["LIMIT", 1]]
(0.1ms) BEGIN
Address Create (43.9ms) INSERT INTO "addresses" ("product_id", "city", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["product_id", 1], ["city", "New York"], ["created_at", "2019-02-27 18:57:37.688063"], ["updated_at", "2019-02-27 18:57:37.688063"]]
(0.3ms) COMMIT
=> #<Address:0x00007fb1e4322178 id: 1, product_id: 1, city: "New York", created_at: Wed, 27 Feb 2019 18:57:37 UTC +00:00, updated_at: Wed, 27 Feb 2019 18:57:37 UTC +00:00>
[15] pry(main)> #city = "NEW YORK"
=> "NEW YORK"
[16] pry(main)> Product.joins(:address).where "lower(addresses.city) like ?", #city.downcase
Product Load (0.7ms) SELECT "products".* FROM "products" INNER JOIN "addresses" ON "addresses"."product_id" = "products"."id" WHERE (lower(addresses.city) like 'new york')
=> [#<Product:0x00007fb1e52f5e10 id: 1, name: "First Product", created_at: Wed, 27 Feb 2019 18:57:07 UTC +00:00, updated_at: Wed, 27 Feb 2019 18:57:07 UTC +00:00>]
I have a rails 5 server that is configured to be "Eastern Time (US & Canada)"
The server works great mostly, it stores times in the database in UTC.
For example, if I am in a console and do
Time.zone.now
=> Fri, 27 Oct 2017 15:07:04 EDT -04:00
Which is correct (we have not fall back on time yet)
However if I pull down an active record object:
> s = Schedule.first
Schedule Load (6.2ms) SELECT "schedules".* FROM "schedules" ORDER BY "schedules"."id" ASC LIMIT $1 [["LIMIT", 1]]
=> #<Schedule id: 1, product_id: 1, day: "Monday", start_time: "2000-01-01 22:00:00", end_time: "2000-01-01 23:00:00", size: 25, description: "Grades 3-5", created_at: "2017-08-23 14:16:09", updated_at: "2017-08-23 14:16:09", is_full: false>
2.4.0 :004 > s.start_time
=> Sat, 01 Jan 2000 17:00:00 EST -05:00
As you can see it convert is to Easter Standard time, which is not correct. Is it possible rails is confused or am I doing something wrong?
(using ruby 2.4)
This was user error, the objects date was in EST so Active Record was doing its job, fix was to set it to today and it would be in the right zone.
I recently ran a migration to add a "Rank" column as a float to a model called jokes (it's a reddit-type page on the app). It shows up in my schema, which means to me that the migration was successful, but when I try to use it to order things via the controller or when I look for that column in my rails console I don't see it.
Here's an example of the controller ordering that doesn't work:
#jokes = Joke.where(kids: true, approved: true).order("rank DESC")
And here's the console output which neglects the new "rank" column:
[54] pry(main)> Joke.last
Joke Load (4.7ms) SELECT "jokes".* FROM "jokes" ORDER BY "jokes"."id" DESC LIMIT 1
=> #<Joke:0x007fb52f927e58
id: 16,
title: "Test Joke",
body: "Tested",
kids: false,
mixed: false,
approved: true,
rejected: nil,
user_id: 1,
created_at: Sat, 13 Aug 2016 19:40:14 UTC +00:00,
updated_at: Sat, 13 Aug 2016 19:40:18 UTC +00:00>
Can anyone help me figure out what's going on here?
I've got a model that uses the default Rails serialization to serialize an array. Behold:
class Account < ActiveRecord::Base
serialize :number_of_free_jobs
end
number_of_free_jobs is an array of FixNums, but for some reason Rails is converting all the entries that are 0 into strings, but leaving the rest as FixNums, check it:
account = Account.last
account.number_of_free_jobs = [10, 5, 0, 1]
account.save
account.number_of_free_jobs
=> [10, 5, "0", 1]
Converting the 0 to a String means some comparisons are failing. I can just map the array with to_i but I'm curious as to why this is happening. I'm using Rails 3.2.13 and Ruby 1.9.3
This doesn't occur on my machine(Sqlite3, Rails 3.2.13 & Ruby 1.9.3):
Loading development environment (Rails 3.2.13)
irb(main):001:0> Account
=> Account(id: integer, number_of_free_jobs: string, created_at: datetime, updated_at: datetime)
irb(main):002:0> Account.create
(0.1ms) begin transaction
SQL (9.5ms) INSERT INTO "accounts" ("created_at", "number_of_free_jobs", "updated_at") VALUES (?, ?, ?) [["created_at", Mon, 20 May 2013 18:19:26 UTC +00:00], ["number_of_free_jobs", nil], ["updated_at", Mon, 20 May 2013 18:19:26 UTC +00:00]]
(179.1ms) commit transaction
=> #<Account id: 2, number_of_free_jobs: nil, created_at: "2013-05-20 18:19:26", updated_at: "2013-05-20 18:19:26">
irb(main):003:0> account = Account.last
Account Load (0.3ms) SELECT "accounts".* FROM "accounts" ORDER BY "accounts"."id" DESC LIMIT 1
=> #<Account id: 2, number_of_free_jobs: nil, created_at: "2013-05-20 18:19:26", updated_at: "2013-05-20 18:19:26">
irb(main):004:0> account.number_of_free_jobs = [10, 5, 0, 1]
=> [10, 5, 0, 1]
irb(main):005:0> account.save
(0.1ms) begin transaction
(0.4ms) UPDATE "accounts" SET "number_of_free_jobs" = '---
- 10
- 5
- 0
- 1
', "updated_at" = '2013-05-20 18:19:46.430558' WHERE "accounts"."id" = 2
(155.9ms) commit transaction
=> true
irb(main):006:0> account.number_of_free_jobs
=> [10, 5, 0, 1]
Can you provide steps to reproduce this issue? perhaps a sample app on github which has this error/bug/behaviour?
The problem was with the Tolk gem installing safe_yaml as a dependency. Removing Tolk removed the dependency and zeroes are no longer being converted to strings. Bit of a strange one, I'll look into why safe_yaml does this...