Timezone issue in Rails - ruby-on-rails

I've never had this before, but somehow when I'm combining a date and a time to a concatenated datetime and store it in the db, I'm off by 2 hours. I just noticed when I started using time_ago_in_words, it's always two hours from now when I just saved something new.
Any idea how to overcome this differnece. I think this is the code that's responsible for the difference:
def create_timestamp
self.date = day.to_datetime + time.seconds_since_midnight.seconds
end
In case anyone is wondering, I'm using a seperate date & time picker on my form, so this the before_save method to create one timestamp for the user input.
Upon request, the SQL for an INSERT at 10:47 CEST, Rails app is in UTC btw:
INSERT INTO "reports" ("account_id", "description", "report_category_id", "day", "time", "user_id", "date", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING "id" [["account_id", 2], ["description", ""], ["report_category_id", 4], ["day", "2016-07-30"], ["time", "2000-01-01 10:47:00.000000"], ["user_id", 1], ["date", "2016-07-30 10:47:00.000000"], ["created_at", "2016-07-30 08:47:53.828175"], ["updated_at", "2016-07-30 08:47:53.828175"]]

Related

Not able to display attachement variant in rails react

I have a product image modal
class ProductImage < ApplicationRecord
belongs_to :product
has_many_attached :images do |attachable|
attachable.variant :thumb, resize_to_limit: [100, nil]
end
def attachement_path
Rails.application.routes.url_helpers.rails_representation_url(
images.first, only_path: true
)
end
def attachement_thumb_path
Rails.application.routes.url_helpers.rails_representation_url(
images.first.variant(:thumb).processed, only_path: true
)
end
end
It perfectly generates attachement_path and display the Image but in case of attachement_thumb_path
It throws the following errors
ActiveStorage::Blob Create (0.4ms) INSERT INTO "active_storage_blobs" ("key", "filename", "content_type", "metadata", "byte_size", "checksum", "created_at", "service_name") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id" [["key", "uk368qdr9oq73hdg13mdkicpdwb6"], ["filename", "look15.jpg"], ["content_type", "image/jpeg"], ["metadata", "{\"identified\":true}"], ["byte_size", 14510], ["checksum", "f8/qGVxgNbeK3YZ7t/e/HQ=="], ["created_at", "2022-10-26 11:38:41.592281"], ["service_name", "local"]]
ActiveStorage::Attachment Create (0.8ms) INSERT INTO "active_storage_attachments" ("name", "record_id", "record_type", "blob_id", "created_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["name", "image"], ["record_id", nil], ["record_type", "ActiveStorage::VariantRecord"], ["blob_id", "495f44bb-1b19-4279-8331-d7c8d86758f8"], ["created_at", "2022-10-26 11:38:41.593878"]]
TRANSACTION (0.2ms) ROLLBACK
/Users/apple/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/activerecord-7.0.4/lib/active_record/connection_adapters/postgresql_adapter.rb:768:in `exec_params': PG::NotNullViolation: ERROR: null value in column "record_id" of relation "active_storage_attachments" violates not-null constraint (ActiveRecord::NotNullViolation)
DETAIL: Failing row contains (49bcc6c0-4167-42f4-8687-a245847798ad, image, null, ActiveStorage::VariantRecord, 495f44bb-1b19-4279-8331-d7c8d86758f8, 2022-10-26 11:38:41.593878).
/Users/apple/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/activerecord-7.0.4/lib/active_record/connection_adapters/postgresql_adapter.rb:768:in `exec_params': ERROR: null value in column "record_id" of relation "active_storage_attachments" violates not-null constraint (PG::NotNullViolation)
DETAIL: Failing row contains (49bcc6c0-4167-42f4-8687-a245847798ad, image, null, ActiveStorage::VariantRecord, 495f44bb-1b19-4279-8331-d7c8d86758f8, 2022-10-26 11:38:41.593878).
irb(main):003:0>
If I remove the null: false validation from record column of active_storage_attachments table everything works perfectly But since this table is generated by action storage I dont want to modify it.

Preserving the order of an array when using .where in Rails

I am passing an array of ids to a .where in Rails, but the way it's returned doesn't preserve the order. For example, here's the array:
2.5.1 :043 > company_ids
=> [83, 79, 52, 44, 82]
I am looking for all pages that have those company IDs, but returned in the order of those company IDs that were provided. This is the result if I try to compare:
2.5.1 :044 > Page.where(company_id: company_ids).pluck(:company_id)
(1.1ms) SELECT "pages"."company_id" FROM "pages" WHERE "pages"."company_id" IN ($1, $2, $3, $4, $5) [["company_id", 83], ["company_id", 79], ["company_id", 52], ["company_id", 44], ["company_id", 82]]
=> [83, 82, 52, 44, 79]
I ran across this stackoverflow post (ActiveRecord.find(array_of_ids), preserving order) that seems to provide a solution, but it doesn't work for me. When trying to use Page.where(company_id: company_ids).order("field(company_id, #{company_ids.join ','})") as suggested in the stackoverflow post, I get the following error:
2.5.1 :042 > Page.where(company_id: company_ids).order("field(company_id, #{company_ids.join ','})")
Page Load (2.0ms) SELECT "pages".* FROM "pages" WHERE "pages"."company_id" IN ($1, $2, $3, $4, $5) ORDER BY field(company_id, 83,79,52,44,82) LIMIT $6 [["company_id", 83], ["company_id", 79], ["company_id", 52], ["company_id", 44], ["company_id", 82], ["LIMIT", 11]]
Traceback (most recent call last):
ActiveRecord::StatementInvalid (PG::UndefinedFunction: ERROR: function field(bigint, integer, integer, integer, integer, integer) does not exist)
LINE 1: ...ts"."company_id" IN ($1, $2, $3, $4, $5) ORDER BY field(comp...
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
: SELECT "pages".* FROM "pages" WHERE "pages"."company_id" IN ($1, $2, $3, $4, $5) ORDER BY field(company_id, 83,79,52,44,82) LIMIT $6
I just simply want to call Pages.where(company_id: company_ids) and get the pages back based on order of company_ids that was provided.
As a workaround, I am using this:
company_ids = companies.order("full_name ASC").pluck(:id)
pages = []
company_ids.each {|c| pages << Page.find_by(company_id: c)}
but seems like that would be inefficient if there are thousands of records. or even just hundreds.
The problem is you're using a MySQL function (field), but the RDBMS you're using is PostgreSQL.
You can try with position, using the row company_id and the array of ids concatenated:
Page.where(company_id: company_ids).order("position(company_id::text in '#{ids.join(',')}')")
Use:
Page.where(company_id: company_ids).order(Arel.sql("position(company_id::text in '#{ids.join(',')}')"))
if you're getting a deprecation warning.
There also exists the possibility to use find, which as stated in the doc says The returned records are in the same order as the ids you provide. Although I don't know if it applies for your case.

creation of a nested_attributes makes before_create not work

I'm tried to create a User in the console doing:
2.2.1 :012 > u.save!
(0.2ms) BEGIN
User Exists (0.7ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('noc#co.co') LIMIT 1
SQL (2.1ms) INSERT INTO "users" ("id", "first_name", "last_name", "email", "title", "time_zone", "company_id", "password_digest", "created_at", "updated_at", "activation_digest") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING "id" [["id", 200], ["first_name", "Random"], ["last_name", "Dude"], ["email", "noc#co.co"], ["title", "CEO"], ["time_zone", "Stockholm"], ["company_id", 1], ["password_digest", "$2a$10$bHHA/JP5IMrucGUXRWMpsO8sInaouSqn48M.fDHpjGdvedu3Napra"], ["created_at", "2015-10-11 23:09:38.213109"], ["updated_at", "2015-10-11 23:09:38.213109"], ["activation_digest", "$2a$10$WF3bUOtbC1gk4ZnX58cJZO5k7P7YV6wvhmwz7EErTdvIseNuy0oyq"]]
2.2.1 :013 > u.activation_token
=> "vKrs0jtvZRiyU-YVE-aPXw"
now when I try to create a user the before_create doesn't work, I tried changing it to before_validation and that didn't work either.
The user is a nested attribute from companies, and is created in Companies#new.
class User < ActiveRecord::Base
belongs_to :company
attr_accessor :remember_token, :activation_token, :reset_token
before_save :downcase_email
before_create :create_activation_digest
now when I do #user.activation_token it returns nil. Here's the console log from when I try it on the app:
Started POST "/companies" for ::1 at 2015-10-12 01:31:47 +0200
Processing by CompaniesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"ZTEtGR2Dd1FDDYm9j4/SiqSTP646R8gctFx4aJHM9QDP+RQky8SG6gkomLbf+E+LgMi+aah1YOhCkUsg3uSYoQ==", "company"=>{"time_zone"=>"Stockholm", "users_attributes"=>{"0"=>{"first_name"=>"swaga", "last_name"=>"swaga", "email"=>"swaga#wkoa.com", "password"=>"[FILTERED]"}}, "name"=>"swaga"}, "commit"=>"Create Company"}
(0.2ms) BEGIN
User Exists (1.3ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('swaga#wkoa.com') LIMIT 1
SQL (7.1ms) INSERT INTO "companies" ("name", "time_zone", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["name", "swaga"], ["time_zone", "Stockholm"], ["created_at", "2015-10-11 23:31:47.380530"], ["updated_at", "2015-10-11 23:31:47.380530"]]
SQL (0.5ms) INSERT INTO "users" ("first_name", "last_name", "email", "password_digest", "activation_digest", "company_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id" [["first_name", "swaga"], ["last_name", "swaga"], ["email", "swaga#wkoa.com"], ["password_digest", "$2a$10$3GsPACTg5HPodiqdedsCvu52N64BEE3/fA77p.oBHAhM51zCSzUV."], ["activation_digest", "$2a$10$75y9jP.eZxmWI1KjHZrg3.DuB5GSwiS2UsaQdtV25ClBHDi.z4Pte"], ["company_id", 8], ["created_at", "2015-10-11 23:31:47.390462"], ["updated_at", "2015-10-11 23:31:47.390462"]]
(6.7ms) COMMIT
User Load (0.9ms) SELECT "users".* FROM "users" WHERE "users"."company_id" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["company_id", 8]]
Rendered user_mailer/account_activation.html.erb within layouts/mailer (7.8ms)
UserMailer#account_activation: processed outbound mail in 29.2ms
Completed 500 Internal Server Error in 380ms (ActiveRecord: 16.9ms)
ActionController::UrlGenerationError - No route matches {:action=>"edit", :controller=>"account_activations", :email=>"swaga#wkoa.com", :id=>nil} missing required keys: [:id]:
now I see that the activation_digest is returned, so I think the issue is literarily just the before_create not working? Which is weird because then it shouldn't be able to create an activation digest as the two are connected:
# Creates and assigns the activation token and digest.
def create_activation_digest
self.activation_token = User.new_token
self.activation_digest = User.digest(activation_token)
end
Your error says:
ActionController::UrlGenerationError - No route matches {:action=>"edit", :controller=>"account_activations", :email=>"swaga#wkoa.com", :id=>nil} missing required keys: [:id]:
Seems like, in your view, you are calling edit_account_activation_path without the id param and that's creating the problem for you. Try to send the user.id as a parameter in the edit_account_activation_path call.
Something like this:
edit_account_activation_path(user.email, user.id)
That should fix your issue.

How globalize gem decides which content goes to translated table?

In my rails 4.2 app I have set it as the default locale by setting it in config/application.rb:
config.i18n.default_locale = :it
I have a simple "product" model
class Product < ActiveRecord::Base
translates :name, :description
end
My need is when I18n.locale = :it the content should be written in "products" table while for all others locales the content shoud go in the "product_translations" table.
Currently what happens is the following:
if
config.i18n.default_locale = :en
content is written to the "products" table, for all different locales the content goes to the "product_translations" table.
How can I change this?
EDIT
Using the console to test globalize behaviour I found that maybe I did not understand how globalize should work.
I was expecting that the "products" table is filled with default_locale (in my case :it) and the "product_translations" table is filled with other locales (:en, :fr, :de and so on).
Instead I see that whichever the locale is, fields that are indicated as
translates :name, :description
are always written in "product_translations" and "product" table only contains those fields that are not translated (in my case uom (unit of measure).
This is the output of the console after saving a new product with :en as locale.
[18] pry(main)> en_p=Product.create(:name=>"butter",
:description => "82% min fat butter",
:uom => "kg") (0.3ms)
BEGIN
SQL (0.7ms)
INSERT INTO "products" ("uom", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"
[
["uom", "kg"],
["created_at", "2015-07-14 05:49:09.097092"],
["updated_at", "2015-07-14 05:49:09.097092"]
]
SQL (0.7ms)
INSERT INTO "product_translations" ("locale",
"name",
"description",
"product_id",
"created_at",
"updated_at")
VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id"
[
["locale", "en"],
["name", "butter"],
["description", "82% min fat butter"],
["product_id", 5],
["created_at", "2015-07-14 05:49:09.116683"],
["updated_at", "2015-07-14 05:49:09.116683"]
]
(15.9ms)
COMMIT
=> #<Product:0xb63d3568
id: 5,
name: "butter",
description: "82% min fat butter",
uom: "kg",
created_at: Tue, 14 Jul 2015 05:49:09 UTC +00:00,
updated_at: Tue, 14 Jul 2015 05:49:09 UTC +00:00>
[19] pry(main)> I18n.locale=:it
=> :it
[20] pry(main)> it_p=Product.create(:name=>"olio di oliva EVO",
:description => "Olio di oliva extravergine spremuto a freddo",
:uom => "kg") (0.4ms)
BEGIN
SQL (0.5ms)
INSERT INTO "products" ("uom", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"
[
["uom", "kg"],
["created_at", "2015-07-14 05:51:34.772755"],
["updated_at", "2015-07-14 05:51:34.772755"]
]
SQL (0.8ms)
INSERT INTO "product_translations" ("locale",
"name",
"description",
"product_id",
"created_at",
"updated_at")
VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id"
[
["locale", "it"],
["name", "olio di oliva extravergine"],
["description", "Olio di oliva extravergine ottenuto unicamente per spremitura"],
["product_id", 6],
["created_at", "2015-07-14 05:51:34.779220"],
["updated_at", "2015-07-14 05:51:34.779220"]
]
(16.1ms)
COMMIT
=> #<Product:0xb6315ce8
id: 6,
name: "olio di oliva extravergine",
description: "Olio di oliva extravergine ottenuto unicamente per spremitura",
uom: "kg",
created_at: Tue, 14 Jul 2015 05:51:34 UTC +00:00,
updated_at: Tue, 14 Jul 2015 05:51:34 UTC +00:00>
Is this the default behaviour?
Do I need to remove translatable fields from the original table?

syntax error with hstore postgres Rails4

Hi I am having a postgres syntax error that I cant seem to track down when using HSTORE
ERROR:
2.0.0p247 :021 > e.save
(218.8ms) BEGIN
SQL (219.8ms) INSERT INTO "communications" ("created_at", "incoming", "properties", "type", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["created_at", Thu, 19 Sep 2013 23:49:14 EST +10:00], ["incoming", true], ["propertie
s", "{\"to\":\"First email test!\"}"], ["type", "Email"], ["updated_at", Thu, 19 Sep 2013 23:49:14 EST +10:00]]
PG::InternalError: ERROR: Syntax error near 'e' at position 13
: INSERT INTO "communications" ("created_at", "incoming", "properties", "type", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id"
(218.4ms) ROLLBACK
That error is from the rails console when I try to save a Email record, in my app email inherits from the Communication model and the records are stored in the "communications" table in the database.
MODELS:
class Communication < ActiveRecord::Base
belongs_to :patient
belongs_to :practice
end
and...
class Email < Communication
store_accessor :properties, :to, :cc, :bcc, :message, :subject
end
Not sure why but couple of days later maybe the DB or a server restart has fixed the problem... all good thanks for your assistance #user647622

Resources