I was upgrading the Ruby on Rails application from 6.0 to 6.1. When checking the start_date which is having having extra precision value when it comes to 6.1
2.7.0 :001 > User.last.created_at
User Load (11.4ms) SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT $1 [["LIMIT", 1]]
=> Sat, 10 Oct 2015 11:36:14.042865000 UTC +00:00
2.7.0 :002 >
When it comes to 6.0, we are no longer has this issue, it is having below values.
2.7.0 :001 > User.last.created_at
User Load (2.0ms) SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT $1 [["LIMIT", 1]]
=> Sat, 10 Oct 2015 11:36:14 UTC +00:00
2.7.0 :002 >
Which is causing all the specs to fails. The database used is postgres and I have research on this and there is not much of a fix on this. The field is timestamp field and it is not a precision value encoded.
Related
I have a Rails app with a users table. PostgreSQL is the database. For some reason, all updates to one of the user records succeed and then silently revert. What is going on?
Broken:
> u = User.find_by(username: 'alice')
> u.last_access
=> Thu, 19 Jul 2018 17:59:35 UTC +00:00
> u.last_access -= 20.days
=> Fri, 29 Jun 2018 17:59:35 UTC +00:00
> u.save!
(1.6ms) BEGIN
...
User Update (1.4ms) UPDATE "users" SET "updated_at" = $1, "last_access" = $2 WHERE "users"."id" = $3 [["updated_at", "2019-01-14 19:02:56.271382"], ["last_access", "2018-06-29 17:59:35"], ["id", 1]]
(0.8ms) COMMIT
=> true
> reload!
> User.find_by(username: 'alice').last_access
=> Thu, 19 Jul 2018 17:59:35 UTC +00:00
> # WHY NOT 29 JUN???
The same operations work for a different user:
> u = User.find_by(username: 'bob')
> u.last_access
=> Mon, 24 Dec 2018 03:33:47 UTC +00:00
> u.last_access -= 20.days
=> Tue, 04 Dec 2018 03:33:47 UTC +00:00
> u.save!
(1.8ms) BEGIN
...
User Update (6.3ms) UPDATE "users" SET "updated_at" = $1, "last_access" = $2 WHERE "users"."id" = $3 [["updated_at", "2019-01-14 18:59:56.087223"], ["last_access", "2018-12-04 03:33:47"], ["id", 2]]
(2.0ms) COMMIT
=> true
> reload!
> User.find_by(username: 'bob').last_access
=> Tue, 04 Dec 2018 03:33:47 UTC +00:00
> # GOOD
I'm using the paper_trail gem for versioning, but I can't find any feature for freezing objects in that gem.
paper_trail is configured to ignore the last_access column:
has_paper_trail ignore: %i[created_at last_access last_login updated_at]
There is a PostgreSQL index on the column:
t.index ["last_access", "last_login"], name: "index_users_on_last_access_and_last_login", using: :btree
The broken user record isn't frozen in ActiveRecord:
> User.find_by(username: 'alice').frozen?
=> false
If you execute the update on the database directly does the change take affect? For instance, you could do:
User.connection.execute 'UPDATE "users" SET "last_access" = \'2018-12-04 03:33:47\' WHERE username = 'alice'
If the change doesn't take affect at that point then I would suspect that there is a trigger or something in your database that is causing the strange behavior.
Edit:
It's very strange to me that your log shows a successful update from Rails but the record isn't actually being changed. I'm still not convinced that there isn't something going on in the database.
Try doing a schema dump of that table and carefully look through it for any triggers that might be causing the value to be changed out from under you.
pg_dump -t 'public.users' --schema-only DB_NAME
I'm trying to build a choose your own adventure game using Ruby on Rails and AJAX calls, where the games are user owned resources, and each game has a sentence column, expecting an array of strings.
game {
id: 16,
sentences: ['hello', 'world']
}
The above does not work when passed in as the data on an AJAX patch request (though I get 200 okay), neither does the hail-mary version of:
game {
id: 16,
sentences: 'hello'
}
The rails local server states that sentences are an unpermitted parameter.
started PATCH "/games/21" for ::1 at 2018-03-18 21:11:12 -0400
Processing by GamesController#update as */*
Parameters: {"game"=>{"id"=>"21", "sentences"=>["This is it: the end. You were wrong."]}, "id"=>"21"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."token" = $1 LIMIT $2 [["token", "8efb6bc10343a4415f6cbcb16d5184f2"], ["LIMIT", 1]]
Game Load (0.4ms) SELECT "games".* FROM "games" WHERE "games"."user_id" = $1 AND "games"."id" = $2 LIMIT $3 [["user_id", 2], ["id", 21], ["LIMIT", 1]]
Unpermitted parameters: :id, :sentences
(0.1ms) BEGIN
(0.1ms) COMMIT
[active_model_serializers] Rendered GameSerializer with ActiveModelSerializers::Adapter::Json (0.38ms)
Completed 200 OK in 5ms (Views: 0.7ms | ActiveRecord: 0.9ms)
This is maddening, because the parameter is specifically permitted in the controller.
def game_params
params.require(:game).permit(:hope, :wisdom, :user_id, :mnemonic, :sentences)
end
I can't get the sentences column to update using AJAX, though I'd added a method to the game model per this blog post's advice.
class Game < ApplicationRecord
belongs_to :user
def add_sentence(words)
sentences_will_change!
update_attributes sentences: sentences.push(words)
end
end
I can definitely update in the Rails console.
[3] pry(main)> game = Game.where(:id => 16).first
Game Load (0.3ms) SELECT "games".* FROM "games" WHERE
"games"."id" = $1 ORDER BY "games"."id" ASC LIMIT $2 [["id", 16],
["LIMIT", 1]]
=> #<Game:0x007ff420f750f0
id: 16,
hope: nil,
wisdom: nil,
created_at: Mon, 19 Mar 2018 00:33:57 UTC +00:00,
updated_at: Mon, 19 Mar 2018 00:33:57 UTC +00:00,
user_id: 1,
mnemonic: "ah",
sentences: ["hello", "world"]>
[8] pry(main)> game.update(sentences: ['hello', 'world', 'again'])
(0.2ms) BEGIN
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
SQL (0.4ms) UPDATE "games" SET "updated_at" = $1, "sentences" = $2 WHERE "games"."id" = $3 [["updated_at", "2018-03-19 00:37:36.428710"], ["sentences", "{hello,world,again}"], ["id", 16]]
(5.6ms) COMMIT
=> true
[10] pry(main)> game
=> #<Game:0x007ff420f750f0
id: 16,
hope: nil,
wisdom: nil,
created_at: Mon, 19 Mar 2018 00:33:57 UTC +00:00,
updated_at: Mon, 19 Mar 2018 00:37:36 UTC +00:00,
user_id: 1,
mnemonic: "ah",
sentences: ["hello", "world", "again"]>
[11] pry(main)>
Please help? I apologize for the foolishness of the question, I just can't figure out what is going wrong.
One issue appears to be that you don't actually have the :id in your permitted params, yet you are passing an id key in the provided examples.
For the sentences, try mapping the sentences key in your permitted params to an empty array:
def game_params
params.require(:game).permit(:hope, :wisdom, :user_id, :mnemonic, sentences: [])
end
More information in this stack overflow comment: https://stackoverflow.com/a/16555975/2909095
Is there a way to find a record by created_at: beginning_of_week?
Something like:
Message.find_by(created_at: Date.today.beginning_of_week).
But it doesn't work.
Because created_at is a DateTime object which includes both a Date and Time value, then your
Message.find_by(created_at: Date.today.beginning_of_week)
# Message Load (6.2ms) SELECT "messages".* FROM "messages" WHERE "messages"."created_at" = $1 LIMIT $2 [["created_at", "2018-01-29"], ["LIMIT", 1]]
... will try to find a record at exactly 2018-01-29 00:00:00 which is a Message record that is exactly created at midnight, instead of 2018-01-29 that you might have expected. You do not want that and instead want ANY record that is created in that day (as far as I understood your question). So, you can try the following instead.
date_beginning_this_week = Date.today.beginning_of_week
Message.where(created_at: date_beginning_this_week..(date_beginning_this_week + 1.day))
# Message Load (0.2ms) SELECT "messages".* FROM "messages" WHERE ("messages"."created_at" BETWEEN $1 AND $2) LIMIT $3 [["created_at", "2018-01-29"], ["created_at", "2018-01-30"], ["LIMIT", 11]]
When I open the console of an existing application and type in :
2.1.1 :001 > User.first
User Load (17.6ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1
=> #<User id: xxxx .... >
typing the query next time :
2.1.1 :002 > User.first
User Load (0.8ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1
=> #<User id: xxxx .... >
You can see the difference between the time taken by rails to query the database. Is something like caching available in console. How does this behave in running applications. Does it more time or even it is cached, where exactly does it do it.
The database server caches queries in the query cache.
See here for documentation on the mysql database query cache: https://dev.mysql.com/doc/refman/5.1/en/query-cache.html
ActiveRecord also performs query caching:
http://edgeguides.rubyonrails.org/caching_with_rails.html
Both of these may be happening depending on your system configuration.
If you're using rails 4, the database connection is not established straight away, until you make a query so:
2.1.1 :001 > User
=> User(no database connection)
2.1.1 :002 > User.first
User Load (28.8ms)
2.1.1 :003 > User.first
User Load (1.9ms)
2.1.1 :004 > User.last
User Load (2.8ms)
So the initial query is establishing a database connection. Those after are then using the cache (as mentioned in other answer) and already established connection.
Hello friends I want to ask them how to make rails console
does not show me the sqlite consult
Loading development environment (Rails 4.0.5)
2.0.0-p481 :001 > last_user=User.last
User Load (0.3ms) SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT 1
=> #<User id: 5, name: "Juan", email: "Lopez", created_at: "2014-06-02 19:50:48", updated_at: "2014-06-02 19:50:48">
I do not want to show this
User Load (0.3ms) SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT 1
In console type:
ActiveRecord::Base.logger = nil