Related
I have a dedicated service used to push on an jsonb column timestamps about some events.
Configuration:
pg: 1.2.2
PostgreSQL: 11.4
Rails: 6.0.2.1
Ruby: 2.6.5
Here is the schema of my table:
create_table "invitations", force: :cascade do |t|
t.uuid "uuid", default: -> { "gen_random_uuid()" }, null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.jsonb "notification_statuses", default: {}, null: false
end
Here is the typical jsonb I have for the column notification_statuses:
{emails: [{created_at: "some date", sent_at: "some date2"},
{created_at: "some other date", sent_at: "some other date2"}]}
Here is the code:
class MyNotificationManager
def initialize(invitation_id)
#invitation = Invitation.find(invitation_id)
end
def start_new_notification_status(type)
#invitation.reload.with_lock do
#invitation.notification_statuses[type] = [] unless #invitation.notification_statuses.key?(type)
hsh = { created_at: Time.zone.now, sent_at: nil }
#invitation.notification_statuses[type].push(hsh)
#invitation.save!
puts "push #{#invitation.notification_statuses[type].count}"
end
end
end
Here is the test:
describe '#start_new_notification_status' do
subject { MyNotificationManager }
describe "with concurrency" do
let(:concurrency_level) { 4 }
let!(:invitation) { create(:invitation) }
it "updates invitation one at the time" do
expect(ActiveRecord::Base.connection.pool.size).to eq(5)
fail_occurred = false
wait_for_it = true
threads = concurrency_level.times.map do |i|
Thread.new do
true while wait_for_it
begin
serv = subject.new(invitation.id)
serv.start_new_notification_status('emails')
rescue StandardError => err
fail_occurred = true
end
end
end
wait_for_it = false
threads.each(&:join)
expect(fail_occurred).not_to be_truthy
expect(invitation.reload.notification_statuses['emails'].count).to eq(concurrency_level)
end
end
end
Finally, my RSpec logs:
Event::NotificationManager
#start_new_notification_status
with concurrency
push 1
push 2
push 2
push 2
Failure/Error: expect(invitation.reload.notification_statuses['emails'].count).to eq(concurrency_level)
expected: 4
got: 2
What am I missing? Logs should obviously be:
Event::NotificationManager
#start_new_notification_status
with concurrency
push 1
push 2
push 3
push 4
Here are my logs.
(0.5ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "schema_sha1"]]
(0.7ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
(0.9ms) BEGIN
(0.3ms) SAVEPOINT active_record_1
Address Create (19.8ms) INSERT INTO "addresses" ("uuid", "line1", "line2", "locality", "zip_postcode", "country_province", "country", "latitude", "longitude", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING "id" [["uuid", "6ca512f7-aa9d-4deb-9fce-7ce3e878f5ee"], ["line1", "27862 Kautzer Dam"], ["line2", "Apt. 831"], ["locality", "West Gladys"], ["zip_postcode", "27812-2854"], ["country_province", "North Carolina"], ["country", "Saint Kitts and Nevis"], ["latitude", 6.990987893090221], ["longitude", -79.50793749705787], ["created_at", "2020-04-20 07:49:21.760116"], ["updated_at", "2020-04-20 07:49:21.760116"]]
(0.3ms) RELEASE SAVEPOINT active_record_1
(0.3ms) SAVEPOINT active_record_1
Establishment Create (14.0ms) INSERT INTO "establishments" ("name", "contact_name", "description", "note", "insta_user_name", "address_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id" [["name", "Stehr-Donnelly"], ["contact_name", "Narcisa"], ["description", "Asperiores voluptates consequuntur."], ["note", "Dolore qui."], ["insta_user_name", "berta.king"], ["address_id", 1], ["created_at", "2020-04-20 07:49:21.792061"], ["updated_at", "2020-04-20 07:49:21.792061"]]
ActsAsTaggableOn::Tagging Load (0.6ms) SELECT "taggings".* FROM "taggings" WHERE "taggings"."taggable_id" = $1 AND "taggings"."taggable_type" = $2 [["taggable_id", 1], ["taggable_type", "Establishment"]]
(0.2ms) RELEASE SAVEPOINT active_record_1
(0.3ms) SAVEPOINT active_record_1
(1.0ms) SELECT COUNT(*) FROM "events" WHERE "events"."establishment_id" = $1 AND ((start_at <= '2020-04-22 16:05:59' AND end_at >= '2020-04-22 16:05:59' AND end_at <= '2020-04-22 18:05:59') OR
(end_at >= '2020-04-22 18:05:59' AND start_at <= '2020-04-22 18:05:59' AND start_at >= '2020-04-22 16:05:59') OR
(start_at >= '2020-04-22 16:05:59' AND end_at <= '2020-04-22 18:05:59') OR
(start_at <= '2020-04-22 16:05:59' AND end_at >= '2020-04-22 18:05:59')) [["establishment_id", 1]]
Event Create (17.1ms) INSERT INTO "events" ("uuid", "establishment_id", "name", "start_at", "end_at", "max_female_guest", "max_male_guest", "created_at", "updated_at", "published") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING "id" [["uuid", "f110cba0-1f97-45ed-bc84-a8bebc73b8f8"], ["establishment_id", 1], ["name", "Clifford Kulas Conroy"], ["start_at", "2020-04-22 16:05:59"], ["end_at", "2020-04-22 18:05:59"], ["max_female_guest", 5], ["max_male_guest", 5], ["created_at", "2020-04-20 07:49:21.830331"], ["updated_at", "2020-04-20 07:49:21.830331"], ["published", true]]
Establishment Update All (0.6ms) UPDATE "establishments" SET "events_count" = COALESCE("events_count", 0) + $1 WHERE "establishments"."id" = $2 [["events_count", 1], ["id", 1]]
(0.2ms) RELEASE SAVEPOINT active_record_1
(0.4ms) SAVEPOINT active_record_1
Area Create (8.1ms) INSERT INTO "areas" ("uuid", "name", "slug", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["uuid", "e13cec8d-4767-490f-a909-f07970006743"], ["name", "Derick Robel"], ["slug", "derick-robel"], ["created_at", "2020-04-20 07:49:21.970034"], ["updated_at", "2020-04-20 07:49:21.970034"]]
(0.3ms) RELEASE SAVEPOINT active_record_1
(0.3ms) SAVEPOINT active_record_1
User Exists? (0.9ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = $1 LIMIT $2 [["email", "vernon#bergstrom.biz"], ["LIMIT", 1]]
User Create (18.8ms) INSERT INTO "users" ("uuid", "email", "encrypted_password", "confirmation_token", "confirmed_at", "confirmation_sent_at", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id" [["uuid", "3bb5012a-ff5b-4dc8-b474-98aa06298c5c"], ["email", "vernon#bergstrom.biz"], ["encrypted_password", "$2a$04$dnmdv.wKESDVpFTn9UyqE.uFQwCexFGcmYBdg18HfGrvv0/4xrrQm"], ["confirmation_token", "bfa804e9-cd89-49ba-acb5-3afcfd5425f6"], ["confirmed_at", "2020-04-20 07:49:21.916321"], ["confirmation_sent_at", "2020-04-20 06:49:21.916422"], ["created_at", "2020-04-20 07:49:22.008360"], ["updated_at", "2020-04-20 07:49:22.008360"]]
AreasUser Create (4.8ms) INSERT INTO "areas_users" ("area_id", "user_id") VALUES ($1, $2) [["area_id", 1], ["user_id", 1]]
(0.2ms) RELEASE SAVEPOINT active_record_1
(0.2ms) SAVEPOINT active_record_1
Consumer Create (8.4ms) INSERT INTO "consumers" ("user_id", "first_name", "last_name", "whatsapp_user_name", "phone_number", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["user_id", 1], ["first_name", "Kermit"], ["last_name", "Cremin"], ["whatsapp_user_name", "7a206657-8365-4075-b4e8-b58d421ac2e2"], ["phone_number", "+855 618.798.2641"], ["created_at", "2020-04-20 07:49:22.036784"], ["updated_at", "2020-04-20 07:49:22.036784"]]
(0.3ms) RELEASE SAVEPOINT active_record_1
(0.2ms) SAVEPOINT active_record_1
Guest Create (18.1ms) INSERT INTO "guests" ("uuid", "gender", "birthdate", "profession", "insta_user_name", "consumer_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id" [["uuid", "47d43976-e9a9-49d4-a722-22c62821d3b4"], ["gender", 1], ["birthdate", "1998-09-11 00:00:00"], ["profession", "Global Sales Engineer"], ["insta_user_name", "jeannetta.harber"], ["consumer_id", 1], ["created_at", "2020-04-20 07:49:22.049803"], ["updated_at", "2020-04-20 07:49:22.049803"]]
(0.2ms) RELEASE SAVEPOINT active_record_1
(0.2ms) SAVEPOINT active_record_1
Invitation Create (12.8ms) INSERT INTO "invitations" ("guest_id", "event_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["guest_id", 1], ["event_id", 1], ["created_at", "2020-04-20 07:49:22.071668"], ["updated_at", "2020-04-20 07:49:22.071668"]]
Event Update All (0.5ms) UPDATE "events" SET "invitations_count" = COALESCE("invitations_count", 0) + $1 WHERE "events"."id" = $2 [["invitations_count", 1], ["id", 1]]
(0.2ms) RELEASE SAVEPOINT active_record_1
Invitation Load (0.5ms) SELECT "invitations".* FROM "invitations" WHERE "invitations"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Invitation Load (1.2ms) SELECT "invitations".* FROM "invitations" WHERE "invitations"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Invitation Load (0.3ms) SELECT "invitations".* FROM "invitations" WHERE "invitations"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
(3.3ms) SAVEPOINT active_record_1
Invitation Load (0.9ms) SELECT "invitations".* FROM "invitations" WHERE "invitations"."id" = $1 LIMIT $2 FOR UPDATE [["id", 1], ["LIMIT", 1]]
Guest Load (0.4ms) SELECT "guests".* FROM "guests" WHERE "guests"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Event Load (0.4ms) SELECT "events".* FROM "events" WHERE "events"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Invitation Update (0.7ms) UPDATE "invitations" SET "updated_at" = $1, "notification_statuses" = $2 WHERE "invitations"."id" = $3 [["updated_at", "2020-04-20 07:49:22.111406"], ["notification_statuses", "{\"emails\":[{\"created_at\":\"2020-04-20T07:49:22.105Z\"}]}"], ["id", 1]]
(0.2ms) RELEASE SAVEPOINT active_record_1
Invitation Load (0.4ms) SELECT "invitations".* FROM "invitations" WHERE "invitations"."id" = $1 LIMIT $2 FOR UPDATE [["id", 1], ["LIMIT", 1]]
Invitation Load (0.3ms) SELECT "invitations".* FROM "invitations" WHERE "invitations"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
(0.2ms) SAVEPOINT active_record_1
Invitation Load (1.1ms) SELECT "invitations".* FROM "invitations" WHERE "invitations"."id" = $1 LIMIT $2 FOR UPDATE [["id", 1], ["LIMIT", 1]]
Guest Load (0.9ms) SELECT "guests".* FROM "guests" WHERE "guests"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Event Load (0.3ms) SELECT "events".* FROM "events" WHERE "events"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Invitation Update (0.7ms) UPDATE "invitations" SET "updated_at" = $1, "notification_statuses" = $2 WHERE "invitations"."id" = $3 [["updated_at", "2020-04-20 07:49:22.129222"], ["notification_statuses", "{\"emails\":[{\"created_at\":\"2020-04-20T07:49:22.105Z\"},{\"created_at\":\"2020-04-20T07:49:22.124Z\"}]}"], ["id", 1]]
(0.2ms) RELEASE SAVEPOINT active_record_1
Guest Load (0.3ms) SELECT "guests".* FROM "guests" WHERE "guests"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Invitation Load (1.1ms) SELECT "invitations".* FROM "invitations" WHERE "invitations"."id" = $1 LIMIT $2 FOR UPDATE [["id", 1], ["LIMIT", 1]]
(2.1ms) SAVEPOINT active_record_1
Invitation Update (2.7ms) UPDATE "invitations" SET "updated_at" = $1, "notification_statuses" = $2 WHERE "invitations"."id" = $3 [["updated_at", "2020-04-20 07:49:22.136369"], ["notification_statuses", "{\"emails\":[{\"created_at\":\"2020-04-20T07:49:22.105Z\"},{\"created_at\":\"2020-04-20T07:49:22.124Z\"},{\"created_at\":\"2020-04-20T07:49:22.135Z\"}]}"], ["id", 1]]
(0.5ms) RELEASE SAVEPOINT active_record_1
Invitation Load (4.1ms) SELECT "invitations".* FROM "invitations" WHERE "invitations"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
(1.0ms) ROLLBACK
(0.3ms) BEGIN
(3.4ms) ALTER TABLE "tags" DISABLE TRIGGER ALL;ALTER TABLE "schema_migrations" DISABLE TRIGGER ALL;ALTER TABLE "ar_internal_metadata" DISABLE TRIGGER ALL;ALTER TABLE "areas_establishments" DISABLE TRIGGER ALL;ALTER TABLE "consumer_ratings" DISABLE TRIGGER ALL;ALTER TABLE "addresses" DISABLE TRIGGER ALL;ALTER TABLE "oauth_access_tokens" DISABLE TRIGGER ALL;ALTER TABLE "guests" DISABLE TRIGGER ALL;ALTER TABLE "areas_users" DISABLE TRIGGER ALL;ALTER TABLE "active_storage_blobs" DISABLE TRIGGER ALL;ALTER TABLE "areas" DISABLE TRIGGER ALL;ALTER TABLE "invitations" DISABLE TRIGGER ALL;ALTER TABLE "establishments_managers" DISABLE TRIGGER ALL;ALTER TABLE "consumers" DISABLE TRIGGER ALL;ALTER TABLE "events" DISABLE TRIGGER ALL;ALTER TABLE "taggings" DISABLE TRIGGER ALL;ALTER TABLE "users" DISABLE TRIGGER ALL;ALTER TABLE "oauth_applications" DISABLE TRIGGER ALL;ALTER TABLE "establishments" DISABLE TRIGGER ALL;ALTER TABLE "active_storage_attachments" DISABLE TRIGGER ALL;ALTER TABLE "oauth_access_grants" DISABLE TRIGGER ALL;ALTER TABLE "managers" DISABLE TRIGGER ALL;ALTER TABLE "devices" DISABLE TRIGGER ALL;ALTER TABLE "admins" DISABLE TRIGGER ALL
(5.0ms) COMMIT
(2.3ms) SELECT schemaname || '.' || tablename
FROM pg_tables
WHERE
tablename !~ '_prt_' AND
tablename <> 'schema_migrations' AND tablename <> 'ar_internal_metadata' AND
schemaname = ANY (current_schemas(false))
(1.7ms) select table_name from information_schema.views where table_schema = 'secret_core_test'
(1425.7ms) TRUNCATE TABLE "public"."tags", "public"."areas_establishments", "public"."consumer_ratings", "public"."addresses", "public"."oauth_access_tokens", "public"."guests", "public"."areas_users", "public"."active_storage_blobs", "public"."areas", "public"."invitations", "public"."establishments_managers", "public"."consumers", "public"."events", "public"."taggings", "public"."users", "public"."oauth_applications", "public"."establishments", "public"."active_storage_attachments", "public"."oauth_access_grants", "public"."managers", "public"."devices", "public"."admins" RESTART IDENTITY CASCADE;
(0.5ms) BEGIN
(2.4ms) ALTER TABLE "tags" ENABLE TRIGGER ALL;ALTER TABLE "schema_migrations" ENABLE TRIGGER ALL;ALTER TABLE "ar_internal_metadata" ENABLE TRIGGER ALL;ALTER TABLE "areas_establishments" ENABLE TRIGGER ALL;ALTER TABLE "consumer_ratings" ENABLE TRIGGER ALL;ALTER TABLE "addresses" ENABLE TRIGGER ALL;ALTER TABLE "oauth_access_tokens" ENABLE TRIGGER ALL;ALTER TABLE "guests" ENABLE TRIGGER ALL;ALTER TABLE "areas_users" ENABLE TRIGGER ALL;ALTER TABLE "active_storage_blobs" ENABLE TRIGGER ALL;ALTER TABLE "areas" ENABLE TRIGGER ALL;ALTER TABLE "invitations" ENABLE TRIGGER ALL;ALTER TABLE "establishments_managers" ENABLE TRIGGER ALL;ALTER TABLE "consumers" ENABLE TRIGGER ALL;ALTER TABLE "events" ENABLE TRIGGER ALL;ALTER TABLE "taggings" ENABLE TRIGGER ALL;ALTER TABLE "users" ENABLE TRIGGER ALL;ALTER TABLE "oauth_applications" ENABLE TRIGGER ALL;ALTER TABLE "establishments" ENABLE TRIGGER ALL;ALTER TABLE "active_storage_attachments" ENABLE TRIGGER ALL;ALTER TABLE "oauth_access_grants" ENABLE TRIGGER ALL;ALTER TABLE "managers" ENABLE TRIGGER ALL;ALTER TABLE "devices" ENABLE TRIGGER ALL;ALTER TABLE "admins" ENABLE TRIGGER ALL
(1.8ms) COMMIT
EDIT: It seems that not all SQL updates are generated. I've the exact same number of not stored data on my array than missing SQL updates. Even if #invitation.save! always returns true (I've checked that right now).
**EDIT2: ** Sometime I have the error <RuntimeError: Locking a record with unpersisted changes is not supported. Use saveto persist the changes, orreload to discard them explicitly. But I have a .reload right before .with_lock!. How is this error possible? π€
I have finally fixed it. Problem came from my manager. Here is the fix:
class MyNotificationManager
def initialize(invitation_id)
#invitation = Invitation.find(invitation_id)
end
def start_new_notification_status(type)
Invitation.transaction do
inv = Invitation.lock.find(#invitation.id)
inv.notification_statuses =
init_type_key(#invitation.notification_statuses, type)
inv.notification_statuses[type] =
add_creation_hash(#invitation.notification_statuses[type], details: details)
inv.save!
end
end
end
If I don't lock it before load (pure SQL lock), it does not really lock it. I'm not 100% sure this is a normal behavior. It sound like a bug to me.
P.S: I don't want #invitation to be locked on init so I had to reload it manually.
P.S2: .reload does not work.
I am trying to compare two hashes to see if the values match so i can reconcile some data.
I have a hash of existing accounts and a hash of accounts i need to check if they exist based on the existing accounts to see if it needs to be inserted.
# Reconcile Adaccounts
def self.reconcileAdaccounts(ad_accounts, user_id)
# These are the accounts that exist
existing_accounts = FbAdaccount.active
.select("fb_id")
.where("user_id = ?", user_id)
.as_json
ad_accounts.each do |ad_account|
if #here i would need to check if ad_account["account_id"] matches one of the existing records
p "This one already exists"
p ad_account["account_id"]
else
p "I need to create this one"
p ad_account["account_id"]
end
end
end
I could have nested loops but that does not seem like it would be the best solution, i also tried looking for any rails API functions that could do this but i have not found one.
What is the most efficient way of doing this?
What you're looking for is find_or_create_by. I've additionally wrapped the call in a transaction so all of this hits the database just once βΒ in a single query.
def self.reconcileAdaccounts(ad_accounts, user_id)
FbAdaccount.transaction do
ad_accounts.each do |ad_account|
FbAdaccount.active
.select('fb_id')
.where('user_id = ?', user_id)
.find_or_create_by(ad_account['account_id'])
end
end
end
Transactions
A transaction doesn't magically alter the query, but it wraps it together so that it either all happens together, or doesn't happen at all.
With the following code:
numbers = (3..7).to_a
Ear.transaction do
numbers.each do |number|
Ear.find_or_create_by(bla: number)
end
end
Note the BEGIN and COMMIT statements. They signify where the call starts and ends.
(0.1ms) BEGIN
Ear Load (0.5ms) SELECT "ears".* FROM "ears" WHERE "ears"."bla" = $1 LIMIT $2 [["bla", 3], ["LIMIT", 1]]
Ear Create (0.8ms) INSERT INTO "ears" ("bla", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["bla", 3], ["created_at", "2019-02-05 23:17:28.157989"], ["updated_at", "2019-02-05 23:17:28.157989"]]
Ear Load (0.2ms) SELECT "ears".* FROM "ears" WHERE "ears"."bla" = $1 LIMIT $2 [["bla", 4], ["LIMIT", 1]]
Ear Create (0.2ms) INSERT INTO "ears" ("bla", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["bla", 4], ["created_at", "2019-02-05 23:17:28.160838"], ["updated_at", "2019-02-05 23:17:28.160838"]]
Ear Load (0.1ms) SELECT "ears".* FROM "ears" WHERE "ears"."bla" = $1 LIMIT $2 [["bla", 5], ["LIMIT", 1]]
Ear Create (0.2ms) INSERT INTO "ears" ("bla", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["bla", 5], ["created_at", "2019-02-05 23:17:28.162241"], ["updated_at", "2019-02-05 23:17:28.162241"]]
Ear Load (0.2ms) SELECT "ears".* FROM "ears" WHERE "ears"."bla" = $1 LIMIT $2 [["bla", 6], ["LIMIT", 1]]
Ear Create (0.2ms) INSERT INTO "ears" ("bla", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["bla", 6], ["created_at", "2019-02-05 23:17:28.163794"], ["updated_at", "2019-02-05 23:17:28.163794"]]
Ear Load (0.2ms) SELECT "ears".* FROM "ears" WHERE "ears"."bla" = $1 LIMIT $2 [["bla", 7], ["LIMIT", 1]]
Ear Create (0.2ms) INSERT INTO "ears" ("bla", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["bla", 7], ["created_at", "2019-02-05 23:17:28.165589"], ["updated_at", "2019-02-05 23:17:28.165589"]]
(40.9ms) COMMIT
Now here's the same code, just without a transaction to wrap it in:
numbers = (20..25).to_a
numbers.each do |number|
Ear.find_or_create_by(bla: number)
end
Note the total number BEGIN and COMMIT messages:
Ear Load (249.3ms) SELECT "ears".* FROM "ears" WHERE "ears"."bla" = $1 LIMIT $2 [["bla", 20], ["LIMIT", 1]]
(73.4ms) BEGIN
Ear Create (48.7ms) INSERT INTO "ears" ("bla", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["bla", 20], ["created_at", "2019-02-06 00:12:35.754374"], ["updated_at", "2019-02-06 00:12:35.754374"]]
(79.8ms) COMMIT
Ear Load (0.4ms) SELECT "ears".* FROM "ears" WHERE "ears"."bla" = $1 LIMIT $2 [["bla", 21], ["LIMIT", 1]]
(0.2ms) BEGIN
Ear Create (77.7ms) INSERT INTO "ears" ("bla", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["bla", 21], ["created_at", "2019-02-06 00:12:35.918461"], ["updated_at", "2019-02-06 00:12:35.918461"]]
(0.3ms) COMMIT
Ear Load (0.2ms) SELECT "ears".* FROM "ears" WHERE "ears"."bla" = $1 LIMIT $2 [["bla", 22], ["LIMIT", 1]]
(0.2ms) BEGIN
Ear Create (2.7ms) INSERT INTO "ears" ("bla", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["bla", 22], ["created_at", "2019-02-06 00:12:36.003822"], ["updated_at", "2019-02-06 00:12:36.003822"]]
(110.1ms) COMMIT
Ear Load (0.3ms) SELECT "ears".* FROM "ears" WHERE "ears"."bla" = $1 LIMIT $2 [["bla", 23], ["LIMIT", 1]]
(0.2ms) BEGIN
Ear Create (0.3ms) INSERT INTO "ears" ("bla", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["bla", 23], ["created_at", "2019-02-06 00:12:36.125187"], ["updated_at", "2019-02-06 00:12:36.125187"]]
(37.0ms) COMMIT
Ear Load (0.2ms) SELECT "ears".* FROM "ears" WHERE "ears"."bla" = $1 LIMIT $2 [["bla", 24], ["LIMIT", 1]]
(0.2ms) BEGIN
Ear Create (0.4ms) INSERT INTO "ears" ("bla", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["bla", 24], ["created_at", "2019-02-06 00:12:36.168414"], ["updated_at", "2019-02-06 00:12:36.168414"]]
(72.4ms) COMMIT
Ear Load (0.3ms) SELECT "ears".* FROM "ears" WHERE "ears"."bla" = $1 LIMIT $2 [["bla", 25], ["LIMIT", 1]]
(1.7ms) BEGIN
Ear Create (0.4ms) INSERT INTO "ears" ("bla", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["bla", 25], ["created_at", "2019-02-06 00:12:36.249285"], ["updated_at", "2019-02-06 00:12:36.249285"]]
(121.2ms) COMMIT
I have a request that makes several changes to the same record, however I only need to store a version when one of the attributes changes from false to true. I tried the following:
has_paper_trail on: [:update],
only: {
redone: Proc.new { |srv|
srv.redone == true && srv.redone_was == false
},
}
But I am still getting versions on changes that do not involve the redone attribute changing from false to true... This is an excerpt from the log:
(0.7ms) BEGIN
SQL (11.3ms) UPDATE "servicings" SET "redone" = $1, "redo_reason" = $2, "updated_at" = $3 WHERE "servicings"."id" = $4 [["redone", false], ["redo_reason", nil], ["updated_at", 2018-07-19 22:46:15 UTC], ["id", 218762]]
SQL (9.7ms) INSERT INTO "versions" ("item_type", "item_id", "event", "object", "object_changes", "created_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id" [["item_type", "Servicing"], ["item_id", 218762], ["event", "update"], ["object", "---\nid: 218762\nwork_order_id: 7462\narea_id: 16563\nhigh_priority: false\ncompleted_at: \ncreated_at: 2018-07-10 19:45:36.245612000 Z\nupdated_at: 2018-07-19 22:14:11.143007000 Z\nassignee_id: 90\nclaimed_by_id: \ncompleted_by_id: 90\noccupied_at: \ndeleted_at: \nstatus: open\napproval_status: \nredone: true\nunable_reason: \nredo_reason: testing paper_trail\napproving_user_id: \napproving_user_name: \napproved_at: \n"], ["object_changes", "---\nredone:\n- true\n- false\nredo_reason:\n- testing paper_trail\n- \nupdated_at:\n- 2018-07-19 22:14:11.143007000 Z\n- 2018-07-19 22:46:15.680447100 Z\n"], ["created_at", 2018-07-19 22:46:15 UTC]]
(5.6ms) COMMIT
(2.0ms) BEGIN
(0.8ms) COMMIT
(1.5ms) BEGIN
SQL (9.1ms) UPDATE "servicings" SET "updated_at" = $1, "status" = $2 WHERE "servicings"."id" = $3 [["updated_at", 2018-07-19 22:46:15 UTC], ["status", "completed"], ["id", 218762]]
SQL (2.8ms) INSERT INTO "versions" ("item_type", "item_id", "event", "object", "object_changes", "created_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id" [["item_type", "Servicing"], ["item_id", 218762], ["event", "update"], ["object", "---\nid: 218762\nredone: false\nredo_reason: \nwork_order_id: 7462\narea_id: 16563\nhigh_priority: false\ncompleted_at: \ncreated_at: 2018-07-10 19:45:36.245612000 Z\nupdated_at: 2018-07-19 22:46:15.680447100 Z\nassignee_id: 90\nclaimed_by_id: \ncompleted_by_id: 90\noccupied_at: \ndeleted_at: \nstatus: open\napproval_status: \nunable_reason: \napproving_user_id: \napproving_user_name: \napproved_at: \n"], ["object_changes", "---\nupdated_at:\n- 2018-07-19 22:46:15.680447100 Z\n- 2018-07-19 22:46:15.981721300 Z\nstatus:\n- open\n- completed\n"], ["created_at", 2018-07-19 22:46:15 UTC]]
(8.7ms) COMMIT
WorkOrder Load (15.1ms) SELECT "work_orders".* FROM "work_orders" WHERE "work_orders"."deleted_at" IS NULL AND "work_orders"."id" = $1 LIMIT $2 [["id", 7462], ["LIMIT", 1]]
(1.2ms) BEGIN
SQL (16.3ms) UPDATE "servicings" SET "completed_at" = $1, "updated_at" = $2 WHERE "servicings"."id" = $3 [["completed_at", 2018-07-19 22:46:16 UTC], ["updated_at", 2018-07-19 22:46:16 UTC], ["id", 218762]]
SQL (7.5ms) INSERT INTO "versions" ("item_type", "item_id", "event", "object", "object_changes", "created_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id" [["item_type", "Servicing"], ["item_id", 218762], ["event", "update"], ["object", "---\nid: 218762\nredone: false\nredo_reason: \nwork_order_id: 7462\narea_id: 16563\nhigh_priority: false\ncompleted_at: \ncreated_at: 2018-07-10 19:45:36.245612000 Z\nupdated_at: 2018-07-19 22:46:15.981721300 Z\nassignee_id: 90\nclaimed_by_id: \ncompleted_by_id: 90\noccupied_at: \ndeleted_at: \nstatus: completed\napproval_status: \nunable_reason: \napproving_user_id: \napproving_user_name: \napproved_at: \n"], ["object_changes", "---\ncompleted_at:\n- \n- 2018-07-19 22:46:16.111954100 Z\nupdated_at:\n- 2018-07-19 22:46:15.981721300 Z\n- 2018-07-19 22:46:16.150183500 Z\n"], ["created_at", 2018-07-19 22:46:16 UTC]]
(2.7ms) COMMIT
What could I be doing wrong?
It's probably because PaperTrail's callback executes after the update. If that's the case, redone_was will always be equal to the current redone value.
You should store your redone_was value somewhere before updating.
class Klass
attr_accessor :old_redone_value
before_save :store_old_redone_value
has_paper_trail on: [:update],
only: {
redone: Proc.new { |srv|
srv.redone == true && srv.old_redone_value == false
},
}
def store_old_redone_value
self.old_redone_value = redone_was
end
end
That's the idea. It's not the best solution, and might not work -- but, it'll lead you somewhere.
Just streamlined my dev environment and switched from SQLite3 to PG so it's the same on my production environment.
The same working code that I had before is now taking much, MUCH more time than it did before.
Haven't changed anything except installing pg.
Before PG:
Processing by CollectionsController#show as HTML
Parameters: {"keyword"=>"cat and dog towel", "id"=>"37"}
Collection Load (0.2ms) SELECT "collections".* FROM "collections" WHERE "collections"."id" = ? LIMIT ? [["id", 37], ["LIMIT", 1]]
Seller Load (0.2ms) SELECT "sellers".* FROM "sellers" WHERE "sellers"."id" = ? LIMIT ? [["id", 13], ["LIMIT", 1]]
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 1], ["LIMIT", 1]]
(0.1ms) begin transaction
(0.1ms) commit transaction
Search Load (0.2ms) SELECT "searches".* FROM "searches" WHERE "searches"."term" = ? LIMIT ? [["term", "cat and dog towel"], ["LIMIT", 1]]
Listing Load (1.4ms) SELECT DISTINCT "listings".* FROM "listings" INNER JOIN "listings_searches" ON "listings"."id" = "listings_searches"."listing_id" WHERE "listings_searches"."search_id" = ? ORDER BY "listings"."id" ASC LIMIT ? [["search_id", 775], ["LIMIT", 1]]
Search Load (0.3ms) SELECT "searches".* FROM "searches" WHERE "searches"."term" = ? ORDER BY "searches"."id" ASC LIMIT ? [["term", "Beach Towel"], ["LIMIT", 1]]
(0.1ms) begin transaction
Search Exists (0.2ms) SELECT 1 AS one FROM "searches" WHERE "searches"."term" = ? LIMIT ? [["term", "Beach Towel"], ["LIMIT", 1]]
SQL (0.5ms) INSERT INTO "searches" ("term", "created_at", "updated_at") VALUES (?, ?, ?) [["term", "Beach Towel"], ["created_at", "2018-06-18 12:47:58.519223"], ["updated_at", "2018-06-18 12:47:58.519223"]]
(7.0ms) commit transaction
Item Exists (0.3ms) SELECT 1 AS one FROM "items" WHERE "items"."search_id" = ? AND "items"."collection_id" = 37 LIMIT ? [["search_id", 776], ["LIMIT", 1]]
(0.1ms) begin transaction
Collection Load (0.1ms) SELECT "collections".* FROM "collections" WHERE "collections"."id" = ? LIMIT ? [["id", 37], ["LIMIT", 1]]
Item Exists (0.2ms) SELECT 1 AS one FROM "items" WHERE "items"."collection_id" = ? AND "items"."search_id" = 776 LIMIT ? [["collection_id", 37], ["LIMIT", 1]]
SQL (2.3ms) INSERT INTO "items" ("collection_id", "search_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["collection_id", 37], ["search_id", 776], ["created_at", "2018-06-18 12:47:58.540021"], ["updated_at", "2018-06-18 12:47:58.540021"]]
(6.2ms) commit transaction
Started GET "/sellers/16" for 127.0.0.1 at 2018-06-18 15:48:00 +0300
Processing by SellersController#show as HTML
Parameters: {"id"=>"16"}
Search Load (5.5ms) SELECT "searches".* FROM "searches" WHERE "searches"."term" = ? ORDER BY "searches"."id" ASC LIMIT ? [["term", "Bath Towel"], ["LIMIT", 1]]
(0.1ms) begin transaction
Search Exists (0.2ms) SELECT 1 AS one FROM "searches" WHERE "searches"."term" = ? LIMIT ? [["term", "Bath Towel"], ["LIMIT", 1]]
SQL (1.4ms) INSERT INTO "searches" ("term", "created_at", "updated_at") VALUES (?, ?, ?) [["term", "Bath Towel"], ["created_at", "2018-06-18 12:48:01.250699"], ["updated_at", "2018-06-18 12:48:01.250699"]]
Seller Load (0.3ms) SELECT "sellers".* FROM "sellers" WHERE "sellers"."id" = ? LIMIT ? [["id", 16], ["LIMIT", 1]]
(9.6ms) commit transaction
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 1], ["LIMIT", 1]]
Item Exists (0.3ms) SELECT 1 AS one FROM "items" WHERE "items"."search_id" = ? AND "items"."collection_id" = 37 LIMIT ? [["search_id", 777], ["LIMIT", 1]]
(0.1ms) begin transaction
Collection Load (0.3ms) SELECT "collections".* FROM "collections" WHERE "collections"."id" = ? LIMIT ? [["id", 37], ["LIMIT", 1]]
Item Exists (0.2ms) SELECT 1 AS one FROM "items" WHERE "items"."collection_id" = ? AND "items"."search_id" = 777 LIMIT ? [["collection_id", 37], ["LIMIT", 1]]
SQL (1.0ms) INSERT INTO "items" ("collection_id", "search_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["collection_id", 37], ["search_id", 777], ["created_at", "2018-06-18 12:48:01.285942"], ["updated_at", "2018-06-18 12:48:01.285942"]]
Shop Load (8.8ms) SELECT "shops".* FROM "shops" WHERE "shops"."seller_id" = ? ORDER BY "shops"."id" DESC LIMIT ? [["seller_id", 16], ["LIMIT", 1]]
(40.2ms) commit transaction
Rendering sellers/show.html.erb within layouts/application
(0.4ms) SELECT COUNT(*) FROM "listings" WHERE "listings"."shop_id" = 12
Listing Load (0.4ms) SELECT "listings".* FROM "listings" WHERE "listings"."shop_id" = 12 LIMIT ? OFFSET ? [["LIMIT", 24], ["OFFSET", 0]]
Rendered sellers/show.html.erb within layouts/application (4.8ms)
Rendered layouts/_shim.html.erb (0.4ms)
Rendered layouts/_rails_default.html.erb (93.9ms)
Rendered layouts/_meta.html.erb (0.3ms)
Seller Exists (0.3ms) SELECT 1 AS one FROM "sellers" WHERE "sellers"."user_id" = ? LIMIT ? [["user_id", 1], ["LIMIT", 1]]
Seller Load (0.3ms) SELECT "sellers".* FROM "sellers" WHERE "sellers"."user_id" = ? ORDER BY "sellers"."id" DESC LIMIT ? [["user_id", 1], ["LIMIT", 1]]
Rendered layouts/_header.html.erb (5.5ms)
Seller Load (0.3ms) SELECT "sellers".* FROM "sellers" WHERE "sellers"."user_id" = ? [["user_id", 1]]
Shop Load (0.3ms) SELECT "shops".* FROM "shops" WHERE "shops"."seller_id" = ? ORDER BY "shops"."id" DESC LIMIT ? [["seller_id", 13], ["LIMIT", 1]]
CACHE Shop Load (0.0ms) SELECT "shops".* FROM "shops" WHERE "shops"."seller_id" = ? ORDER BY "shops"."id" DESC LIMIT ? [["seller_id", 16], ["LIMIT", 1]]
Rendered layouts/_sidebar.html.erb (7.3ms)
Rendered layouts/_end_sidebar.html.erb (0.4ms)
Rendered layouts/_footer.html.erb (0.4ms)
Completed 200 OK in 212ms (Views: 120.5ms | ActiveRecord: 12.3ms)
After PG:
Started POST "/collections/1/item/choose.25" for 127.0.0.1 at 2018-06-18 16:56:12 +0300
Processing by ItemsController#choose as
Parameters: {"authenticity_token"=>"11+Rpf2qXEKhQ5vBJLWie2EBg1b2Dtrw8iIgoLwXyvake7+myDrVErcqTwNcPYAZ5xs+zFKXaJjwM7fTakXaoA==", "collection_id"=>"1"}
Collection Load (0.4ms) SELECT "collections".* FROM "collections" WHERE "collections"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Seller Load (0.6ms) SELECT "sellers".* FROM "sellers" WHERE "sellers"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Item Load (0.3ms) SELECT "items".* FROM "items" WHERE "items"."id" = $1 LIMIT $2 [["id", 25], ["LIMIT", 1]]
(0.1ms) BEGIN
Collection Load (0.5ms) SELECT "collections".* FROM "collections" WHERE "collections"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Search Load (0.9ms) SELECT "searches".* FROM "searches" WHERE "searches"."id" = $1 LIMIT $2 [["id", 31], ["LIMIT", 1]]
Item Exists (0.7ms) SELECT 1 AS one FROM "items" WHERE "items"."collection_id" = $1 AND ("items"."id" != $2) AND "items"."search_id" = 31 LIMIT $3 [["collection_id", 1], ["id", 25], ["LIMIT", 1]]
SQL (0.8ms) UPDATE "items" SET "chosen" = $1, "updated_at" = $2 WHERE "items"."id" = $3 [["chosen", "t"], ["updated_at", "2018-06-18 13:56:12.465841"], ["id", 25]]
(2.7ms) COMMIT
(0.4ms) BEGIN
SQL (0.6ms) UPDATE "collections" SET "keyword" = $1, "updated_at" = $2 WHERE "collections"."id" = $3 [["keyword", "Bookish Candles"], ["updated_at", "2018-06-18 13:56:12.473173"], ["id", 1]]
(1.5ms) COMMIT
Search Load (0.6ms) SELECT "searches".* FROM "searches" WHERE "searches"."term" = $1 LIMIT $2 [["term", "Bookish Candles"], ["LIMIT", 1]]
Listing Load (4.1ms) SELECT DISTINCT "listings".* FROM "listings" INNER JOIN "listings_searches" ON "listings"."id" = "listings_searches"."listing_id" WHERE "listings_searches"."search_id" = $1 ORDER BY "listings"."id" ASC LIMIT $2 [["search_id", 31], ["LIMIT", 3]]
Search Load (0.7ms) SELECT "searches".* FROM "searches" WHERE "searches"."term" = $1 ORDER BY "searches"."id" ASC LIMIT $2 [["term", "soy candles"], ["LIMIT", 1]]
(0.2ms) BEGIN
Search Exists (0.8ms) SELECT 1 AS one FROM "searches" WHERE "searches"."term" = $1 LIMIT $2 [["term", "soy candles"], ["LIMIT", 1]]
SQL (0.6ms) INSERT INTO "searches" ("term", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["term", "soy candles"], ["created_at", "2018-06-18 13:56:12.491262"], ["updated_at", "2018-06-18 13:56:12.491262"]]
(2.3ms) COMMIT
Item Exists (0.6ms) SELECT 1 AS one FROM "items" WHERE "items"."search_id" = $1 AND "items"."collection_id" = 1 LIMIT $2 [["search_id", 46], ["LIMIT", 1]]
(0.2ms) BEGIN
Collection Load (1.3ms) SELECT "collections".* FROM "collections" WHERE "collections"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Item Exists (0.7ms) SELECT 1 AS one FROM "items" WHERE "items"."collection_id" = $1 AND "items"."search_id" = 46 LIMIT $2 [["collection_id", 1], ["LIMIT", 1]]
SQL (1.0ms) INSERT INTO "items" ("collection_id", "search_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["collection_id", 1], ["search_id", 46], ["created_at", "2018-06-18 13:56:12.504381"], ["updated_at", "2018-06-18 13:56:12.504381"]]
(1.1ms) COMMIT
Search Load (0.8ms) SELECT "searches".* FROM "searches" WHERE "searches"."term" = $1 ORDER BY "searches"."id" ASC LIMIT $2 [["term", "book candle"], ["LIMIT", 1]]
(0.2ms) BEGIN
Search Exists (0.5ms) SELECT 1 AS one FROM "searches" WHERE "searches"."term" = $1 LIMIT $2 [["term", "book candle"], ["LIMIT", 1]]
SQL (0.5ms) INSERT INTO "searches" ("term", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["term", "book candle"], ["created_at", "2018-06-18 13:56:14.812727"], ["updated_at", "2018-06-18 13:56:14.812727"]]
(2.8ms) COMMIT
Item Exists (0.7ms) SELECT 1 AS one FROM "items" WHERE "items"."search_id" = $1 AND "items"."collection_id" = 1 LIMIT $2 [["search_id", 47], ["LIMIT", 1]]
(0.1ms) BEGIN
Collection Load (1.0ms) SELECT "collections".* FROM "collections" WHERE "collections"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Item Exists (0.6ms) SELECT 1 AS one FROM "items" WHERE "items"."collection_id" = $1 AND "items"."search_id" = 47 LIMIT $2 [["collection_id", 1], ["LIMIT", 1]]
SQL (0.5ms) INSERT INTO "items" ("collection_id", "search_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["collection_id", 1], ["search_id", 47], ["created_at", "2018-06-18 13:56:14.825865"], ["updated_at", "2018-06-18 13:56:14.825865"]]
(1.4ms) COMMIT
Search Load (1.0ms) SELECT "searches".* FROM "searches" WHERE "searches"."term" = $1 ORDER BY "searches"."id" ASC LIMIT $2 [["term", "literary gifts"], ["LIMIT", 1]]
(0.4ms) BEGIN
Search Exists (0.7ms) SELECT 1 AS one FROM "searches" WHERE "searches"."term" = $1 LIMIT $2 [["term", "literary gifts"], ["LIMIT", 1]]
SQL (0.7ms) INSERT INTO "searches" ("term", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["term", "literary gifts"], ["created_at", "2018-06-18 13:56:17.776368"], ["updated_at", "2018-06-18 13:56:17.776368"]]
(2.4ms) COMMIT
Item Exists (0.8ms) SELECT 1 AS one FROM "items" WHERE "items"."search_id" = $1 AND "items"."collection_id" = 1 LIMIT $2 [["search_id", 48], ["LIMIT", 1]]
(0.2ms) BEGIN
Collection Load (1.6ms) SELECT "collections".* FROM "collections" WHERE "collections"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Item Exists (0.8ms) SELECT 1 AS one FROM "items" WHERE "items"."collection_id" = $1 AND "items"."search_id" = 48 LIMIT $2 [["collection_id", 1], ["LIMIT", 1]]
SQL (1.1ms) INSERT INTO "items" ("collection_id", "search_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["collection_id", 1], ["search_id", 48], ["created_at", "2018-06-18 13:56:17.790424"], ["updated_at", "2018-06-18 13:56:17.790424"]]
(1.2ms) COMMIT
Search Load (0.7ms) SELECT "searches".* FROM "searches" WHERE "searches"."term" = $1 ORDER BY "searches"."id" ASC LIMIT $2 [["term", "book candles"], ["LIMIT", 1]]
(0.2ms) BEGIN
Search Exists (0.7ms) SELECT 1 AS one FROM "searches" WHERE "searches"."term" = $1 LIMIT $2 [["term", "book candles"], ["LIMIT", 1]]
SQL (0.6ms) INSERT INTO "searches" ("term", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["term", "book candles"], ["created_at", "2018-06-18 13:56:20.872076"], ["updated_at", "2018-06-18 13:56:20.872076"]]
(1.4ms) COMMIT
Item Exists (0.6ms) SELECT 1 AS one FROM "items" WHERE "items"."search_id" = $1 AND "items"."collection_id" = 1 LIMIT $2 [["search_id", 49], ["LIMIT", 1]]
(0.1ms) BEGIN
Collection Load (0.6ms) SELECT "collections".* FROM "collections" WHERE "collections"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Item Exists (0.7ms) SELECT 1 AS one FROM "items" WHERE "items"."collection_id" = $1 AND "items"."search_id" = 49 LIMIT $2 [["collection_id", 1], ["LIMIT", 1]]
SQL (0.8ms) INSERT INTO "items" ("collection_id", "search_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["collection_id", 1], ["search_id", 49], ["created_at", "2018-06-18 13:56:20.883450"], ["updated_at", "2018-06-18 13:56:20.883450"]]
(2.3ms) COMMIT
Search Load (0.9ms) SELECT "searches".* FROM "searches" WHERE "searches"."term" = $1 ORDER BY "searches"."id" ASC LIMIT $2 [["term", "literary candles"], ["LIMIT", 1]]
(0.2ms) BEGIN
Search Exists (0.5ms) SELECT 1 AS one FROM "searches" WHERE "searches"."term" = $1 LIMIT $2 [["term", "literary candles"], ["LIMIT", 1]]
SQL (0.8ms) INSERT INTO "searches" ("term", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["term", "literary candles"], ["created_at", "2018-06-18 13:56:22.523896"], ["updated_at", "2018-06-18 13:56:22.523896"]]
(1.4ms) COMMIT
Item Exists (0.7ms) SELECT 1 AS one FROM "items" WHERE "items"."search_id" = $1 AND "items"."collection_id" = 1 LIMIT $2 [["search_id", 50], ["LIMIT", 1]]
(0.2ms) BEGIN
Collection Load (0.7ms) SELECT "collections".* FROM "collections" WHERE "collections"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Item Exists (0.9ms) SELECT 1 AS one FROM "items" WHERE "items"."collection_id" = $1 AND "items"."search_id" = 50 LIMIT $2 [["collection_id", 1], ["LIMIT", 1]]
SQL (0.9ms) INSERT INTO "items" ("collection_id", "search_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["collection_id", 1], ["search_id", 50], ["created_at", "2018-06-18 13:56:22.536553"], ["updated_at", "2018-06-18 13:56:22.536553"]]
(2.2ms) COMMIT
Search Load (0.9ms) SELECT "searches".* FROM "searches" WHERE "searches"."term" = $1 ORDER BY "searches"."id" ASC LIMIT $2 [["term", "soy candle"], ["LIMIT", 1]]
Item Exists (0.7ms) SELECT 1 AS one FROM "items" WHERE "items"."search_id" = $1 AND "items"."collection_id" = 1 LIMIT $2 [["search_id", 18], ["LIMIT", 1]]
Search Load (0.6ms) SELECT "searches".* FROM "searches" WHERE "searches"."term" = $1 ORDER BY "searches"."id" ASC LIMIT $2 [["term", "8oz candles"], ["LIMIT", 1]]
(0.3ms) BEGIN
Search Exists (0.6ms) SELECT 1 AS one FROM "searches" WHERE "searches"."term" = $1 LIMIT $2 [["term", "8oz candles"], ["LIMIT", 1]]
SQL (0.5ms) INSERT INTO "searches" ("term", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["term", "8oz candles"], ["created_at", "2018-06-18 13:56:25.455733"], ["updated_at", "2018-06-18 13:56:25.455733"]]
(2.4ms) COMMIT
Item Exists (0.8ms) SELECT 1 AS one FROM "items" WHERE "items"."search_id" = $1 AND "items"."collection_id" = 1 LIMIT $2 [["search_id", 51], ["LIMIT", 1]]
(0.2ms) BEGIN
Collection Load (0.7ms) SELECT "collections".* FROM "collections" WHERE "collections"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Item Exists (0.6ms) SELECT 1 AS one FROM "items" WHERE "items"."collection_id" = $1 AND "items"."search_id" = 51 LIMIT $2 [["collection_id", 1], ["LIMIT", 1]]
SQL (1.0ms) INSERT INTO "items" ("collection_id", "search_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["collection_id", 1], ["search_id", 51], ["created_at", "2018-06-18 13:56:25.468089"], ["updated_at", "2018-06-18 13:56:25.468089"]]
(1.2ms) COMMIT
Search Load (0.7ms) SELECT "searches".* FROM "searches" WHERE "searches"."term" = $1 ORDER BY "searches"."id" ASC LIMIT $2 [["term", "handmade soy candles"], ["LIMIT", 1]]
(0.2ms) BEGIN
Search Exists (0.5ms) SELECT 1 AS one FROM "searches" WHERE "searches"."term" = $1 LIMIT $2 [["term", "handmade soy candles"], ["LIMIT", 1]]
SQL (0.5ms) INSERT INTO "searches" ("term", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["term", "handmade soy candles"], ["created_at", "2018-06-18 13:56:27.445609"], ["updated_at", "2018-06-18 13:56:27.445609"]]
(1.3ms) COMMIT
Item Exists (1.1ms) SELECT 1 AS one FROM "items" WHERE "items"."search_id" = $1 AND "items"."collection_id" = 1 LIMIT $2 [["search_id", 52], ["LIMIT", 1]]
(0.2ms) BEGIN
Collection Load (0.5ms) SELECT "collections".* FROM "collections" WHERE "collections"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Item Exists (0.6ms) SELECT 1 AS one FROM "items" WHERE "items"."collection_id" = $1 AND "items"."search_id" = 52 LIMIT $2 [["collection_id", 1], ["LIMIT", 1]]
SQL (0.6ms) INSERT INTO "items" ("collection_id", "search_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["collection_id", 1], ["search_id", 52], ["created_at", "2018-06-18 13:56:27.457050"], ["updated_at", "2018-06-18 13:56:27.457050"]]
(2.5ms) COMMIT
Search Load (0.7ms) SELECT "searches".* FROM "searches" WHERE "searches"."term" = $1 ORDER BY "searches"."id" ASC LIMIT $2 [["term", "bookish candle"], ["LIMIT", 1]]
Item Exists (0.6ms) SELECT 1 AS one FROM "items" WHERE "items"."search_id" = $1 AND "items"."collection_id" = 1 LIMIT $2 [["search_id", 13], ["LIMIT", 1]]
Search Load (0.5ms) SELECT "searches".* FROM "searches" WHERE "searches"."term" = $1 ORDER BY "searches"."id" ASC LIMIT $2 [["term", "bookish candles"], ["LIMIT", 1]]
(0.2ms) BEGIN
Search Exists (0.5ms) SELECT 1 AS one FROM "searches" WHERE "searches"."term" = $1 LIMIT $2 [["term", "bookish candles"], ["LIMIT", 1]]
SQL (1.0ms) INSERT INTO "searches" ("term", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["term", "bookish candles"], ["created_at", "2018-06-18 13:56:29.102682"], ["updated_at", "2018-06-18 13:56:29.102682"]]
(1.6ms) COMMIT
Item Exists (0.8ms) SELECT 1 AS one FROM "items" WHERE "items"."search_id" = $1 AND "items"."collection_id" = 1 LIMIT $2 [["search_id", 53], ["LIMIT", 1]]
(0.3ms) BEGIN
Collection Load (0.5ms) SELECT "collections".* FROM "collections" WHERE "collections"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Item Exists (0.5ms) SELECT 1 AS one FROM "items" WHERE "items"."collection_id" = $1 AND "items"."search_id" = 53 LIMIT $2 [["collection_id", 1], ["LIMIT", 1]]
SQL (0.6ms) INSERT INTO "items" ("collection_id", "search_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["collection_id", 1], ["search_id", 53], ["created_at", "2018-06-18 13:56:29.114736"], ["updated_at", "2018-06-18 13:56:29.114736"]]
(2.1ms) COMMIT
Search Load (1.0ms) SELECT "searches".* FROM "searches" WHERE "searches"."term" = $1 ORDER BY "searches"."id" ASC LIMIT $2 [["term", "personalized gifts"], ["LIMIT", 1]]
(0.2ms) BEGIN
Search Exists (0.8ms) SELECT 1 AS one FROM "searches" WHERE "searches"."term" = $1 LIMIT $2 [["term", "personalized gifts"], ["LIMIT", 1]]
SQL (0.8ms) INSERT INTO "searches" ("term", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["term", "personalized gifts"], ["created_at", "2018-06-18 13:56:30.446268"], ["updated_at", "2018-06-18 13:56:30.446268"]]
(1.5ms) COMMIT
Item Exists (1.0ms) SELECT 1 AS one FROM "items" WHERE "items"."search_id" = $1 AND "items"."collection_id" = 1 LIMIT $2 [["search_id", 54], ["LIMIT", 1]]
(0.2ms) BEGIN
Collection Load (0.9ms) SELECT "collections".* FROM "collections" WHERE "collections"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Item Exists (0.7ms) SELECT 1 AS one FROM "items" WHERE "items"."collection_id" = $1 AND "items"."search_id" = 54 LIMIT $2 [["collection_id", 1], ["LIMIT", 1]]
SQL (0.8ms) INSERT INTO "items" ("collection_id", "search_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["collection_id", 1], ["search_id", 54], ["created_at", "2018-06-18 13:56:30.459078"], ["updated_at", "2018-06-18 13:56:30.459078"]]
(2.2ms) COMMIT
Search Load (0.7ms) SELECT "searches".* FROM "searches" WHERE "searches"."term" = $1 ORDER BY "searches"."id" ASC LIMIT $2 [["term", "personalized gift"], ["LIMIT", 1]]
(0.3ms) BEGIN
Search Exists (0.5ms) SELECT 1 AS one FROM "searches" WHERE "searches"."term" = $1 LIMIT $2 [["term", "personalized gift"], ["LIMIT", 1]]
SQL (0.6ms) INSERT INTO "searches" ("term", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["term", "personalized gift"], ["created_at", "2018-06-18 13:56:32.460438"], ["updated_at", "2018-06-18 13:56:32.460438"]]
(2.5ms) COMMIT
Item Exists (0.6ms) SELECT 1 AS one FROM "items" WHERE "items"."search_id" = $1 AND "items"."collection_id" = 1 LIMIT $2 [["search_id", 55], ["LIMIT", 1]]
(0.2ms) BEGIN
Collection Load (0.7ms) SELECT "collections".* FROM "collections" WHERE "collections"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Item Exists (0.7ms) SELECT 1 AS one FROM "items" WHERE "items"."collection_id" = $1 AND "items"."search_id" = 55 LIMIT $2 [["collection_id", 1], ["LIMIT", 1]]
SQL (0.7ms) INSERT INTO "items" ("collection_id", "search_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["collection_id", 1], ["search_id", 55], ["created_at", "2018-06-18 13:56:32.474614"], ["updated_at", "2018-06-18 13:56:32.474614"]]
(1.1ms) COMMIT
Search Load (0.8ms) SELECT "searches".* FROM "searches" WHERE "searches"."term" = $1 ORDER BY "searches"."id" ASC LIMIT $2 [["term", "book smell"], ["LIMIT", 1]]
(0.5ms) BEGIN
Search Exists (0.8ms) SELECT 1 AS one FROM "searches" WHERE "searches"."term" = $1 LIMIT $2 [["term", "book smell"], ["LIMIT", 1]]
SQL (0.7ms) INSERT INTO "searches" ("term", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["term", "book smell"], ["created_at", "2018-06-18 13:56:34.573441"], ["updated_at", "2018-06-18 13:56:34.573441"]]
(1.3ms) COMMIT
Item Exists (0.6ms) SELECT 1 AS one FROM "items" WHERE "items"."search_id" = $1 AND "items"."collection_id" = 1 LIMIT $2 [["search_id", 56], ["LIMIT", 1]]
(0.1ms) BEGIN
Collection Load (1.4ms) SELECT "collections".* FROM "collections" WHERE "collections"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Item Exists (0.6ms) SELECT 1 AS one FROM "items" WHERE "items"."collection_id" = $1 AND "items"."search_id" = 56 LIMIT $2 [["collection_id", 1], ["LIMIT", 1]]
SQL (0.6ms) INSERT INTO "items" ("collection_id", "search_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["collection_id", 1], ["search_id", 56], ["created_at", "2018-06-18 13:56:34.585728"], ["updated_at", "2018-06-18 13:56:34.585728"]]
(2.5ms) COMMIT
Redirected to http://localhost:3000/collections/1
Completed 302 Found in 24422ms (ActiveRecord: 153.5ms)
The amount of items I'm inserting varies but even between many different examples, PG always takes longer, even though when looking at those two logs I posted, it seems like SQLite3 is taking longer per transaction.
Is this normal or is there something I can do to optimize it?
Thanks!
Looks like ActiveRecord is responding pretty quickly for both databases:
Sqlite: ActiveRecord: 12.3ms
Postgres: ActiveRecord: 153.5ms
While Postgres is certainly higher, I would think both of those response times would be acceptable, and that they would vary slightly each time you hit that action.
You do, however, have some sort of redirect taking place 302 Redirected to http://localhost:3000/collections/1 that seems to be adding a bunch of time to the request.
You might try making sure that there are no scripts on that page that are gumming up the works. Also, you might make sure that the indexes have been applied to your Postgres database, and also make sure your collections page doesn't have any n+1 queries.
Hard to say more with the limited information given in the question,
<%= f.time_select :exact, {ampm: true, :discard_minute=> true} %> # t.time "exact"
How do I pass the above in params?
session[:challenge_exact] = params[:exact].parse_time_select! # got nil error
session[:challenge_exact] = challenge_params[:exact]
session[:challenge_exact] = [params["challenge"]["exact(1i)"], params["challenge"]["exact(2i)"], params["challenge"]["exact(3i)"], params["challenge"]["exact(4i)"], params["challenge"]["exact(5i)"]].join(',')
None of the above work. After the challenge is created I see that exact: nil even though it was populated in the form.
Started POST "/challenges" for ::1 at 2017-05-02 08:28:31 -0400
Processing by ChallengesController#create as HTML
Parameters: {"utf8"=>"β", "authenticity_token"=>"oN+DzJK+/GGmpTOOVYMUJQdywuENwxhmX/EVeW6NSZ3w1MctoMd/VHS39d+JasEjHujO88nLPSB2qUKEhet5yA==", "challenge"=>{"name"=>"Write 3 Gratitudes", "categorization"=>"health", "category"=>"goal", "deadline(2i)"=>"6", "deadline(3i)"=>"2", "deadline(1i)"=>"2017", "push"=>"0", "message"=>"1", "mail"=>"0", "remind"=>["mon", "thu", ""], "exact(1i)"=>"2017", "exact(2i)"=>"5", "exact(3i)"=>"2", "exact(4i)"=>"08", "exact(5i)"=>"27", "conceal"=>"0"}, "number"=>"", "email"=>"", "button"=>""}
Redirected to http://localhost:3000/signup
Completed 302 Found in 47ms (ActiveRecord: 0.0ms)
After POST challenge a person then creates a user account...
Started POST "/users" for ::1 at 2017-05-03 01:02:13 -0400
Processing by UsersController#create as HTML
Parameters: {"utf8"=>"β", "authenticity_token"=>"4Lv5NSfH9tMnC9+t5bVC5x1d571y0jhwsgvYU3t2sp85XAnNOsHk+FCmtGcj2wJVysV6IlAIzF4jCx1hIofwsNg==", "user"=>{"name"=>"test", "last_name"=>"daddy", "email"=>"testdaddy#gmail.com", "password"=>"[FILTERED]", "time_zone"=>"Eastern Time (US & Canada)", "subscribe"=>"0"}, "button"=>""}
(0.2ms) BEGIN
User Exists (0.5ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('testdaddy#gmail.com') LIMIT 1
SQL (2.3ms) INSERT INTO "users" ("time_zone", "name", "last_name", "subscribe", "email", "password_digest", "number", "created_at", "updated_at", "activation_digest", "activated") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING "id" [["time_zone", "Eastern Time (US & Canada)"], ["name", "test"], ["last_name", "daddy"], ["subscribe", "f"], ["email", "testdaddy#gmail.com"], ["password_digest", "$2a$10$JSSPUl0JDnUXybnAuSnEO.q5DgZscaU3hRpcM4C5L0a0aEtflzb7ne"], ["number", "15169499507"], ["created_at", "2017-05-03 05:02:14.144232"], ["updated_at", "2017-05-03 05:02:14.144232"], ["activation_digest", "$2a$10$NDtWKvxuJm/Hb9YIOzuVIuPpttCZwjsgYws6HhEcbHc.PukxXNpeLa"], ["activated", "t"]]
(18.8ms) COMMIT
(0.2ms) BEGIN
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 16]]
# AS YOU CAN SEE WITH INSERT INTO CHALLENGES FOR SOME REASON THE SESSION PARAMS FOR EXACT ISN'T PASSING FOR EXACT
SQL (0.6ms) INSERT INTO "challenges" ("committed", "name", "categorization", "category", "deadline", "remind", "message", "user_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING "id" [["committed", nil], ["name", "Write 3 Gratitudes"], ["categorization", "health"], ["category", "goal"], ["deadline", "2017-06-03"], ["remind", "---\n- mon\n- thu\n- ''\n"], ["message", "t"], ["user_id", 16], ["created_at", "2017-05-03 05:02:14.434251"], ["updated_at", "2017-05-03 05:02:14.434251"]]
ActsAsTaggableOn::Tag Load (0.6ms) SELECT "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."taggable_id" = $1 AND "taggings"."taggable_type" = $2 AND (taggings.context = 'tags' AND taggings.tagger_id IS NULL) [["taggable_id", 40], ["taggable_type", "Challenge"]]
ActsAsTaggableOn::Tag Load (0.8ms) SELECT "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."taggable_id" = $1 AND "taggings"."taggable_type" = $2 AND (taggings.context = 'tags' AND
taggings.tagger_id = 16 AND
taggings.tagger_type = 'User') [["taggable_id", 40], ["taggable_type", "Challenge"]]
(17.2ms) COMMIT
Redirected to http://localhost:3000/
How it appears in console...
exact: 2000-01-01 02:32:00 UTC>
You can access exact params like:
> params[:challenge]["exact(1i)"]
#=> "2017"
> params[:challenge]["exact(2i)"]
#=> "5"
> params[:challenge]["exact(3i)"]
#=> "2"
> params[:challenge]["exact(4i)"]
#=> "08"
> params[:challenge]["exact(5i)"]
#=> "27"
You can parse time like this:
exact_time = "#{params[:challenge]['exact(4i)']}:#{params[:challenge]['exact(5i)']}"
#=> "08:27"
> session[:challenge_exact] = Time.parse(exact_time)
#=> 2017-05-03 08:27:00 +0530
I would do:
session[:challenge_exact] = components_to_absolute(params[:exact])
def components_to_absolute(components)
DateTime.new(components['exact(1i)'].to_i,
components['exact(2i)'].to_i,
components['exact(3i)'].to_i,
components['exact(4i)'].to_i,
components['exact(5i)'].to_i)
end