Rails cannot write to database field - ruby-on-rails

I am trying to do a very simple update on a field that does not have any validation whatsoever. However, the update always fails. Here is what the code looks like:
# model
class Event < ActiveRecord::Base
attr_accessible :start_time
..
end
# migration
class CreateEvents < ActiveRecord::Migration
def change
t.datetime :start_time
end
end
# console
Event.first.update_attribute(:start_time, "02:00")
The query that was run in the Rails log does not even include the start_time attribute!
(0.2ms) BEGIN
(4.5ms) UPDATE events SET updated_at =
'2012-07-24 19:51:33', repeat_days = '--- \n- wed\n- sat\n- sun\n',
event_date_list = '--- []\n\n' WHERE events.id = 3763
(5.5ms) COMMIT
I cannot begin to make sense of this. Can anyone help me understand the root cause of this problem?

You are a passing it a string, not a Date, Time, or Datetime object.
It looks like you just want to store the time, not the date attached. But maybe you meant to attach a date as well. If you want to store the date as well, look up the Datetime class.
If you want to store just the time (hours, minutes, and seconds), then I would suggest you change your start_time field to be an integer, and store the seconds: 2.hours or 2.hours + 4.minutes + 6.seconds.
You can convert that easily in to time again.

Related

Seeding datetime into database fails

I am trying to seed a datetime into my PostgreSQL database:
6.times do |spots|
title = "FUN STUFF NUMBER #{spots+1}"
content = Faker::Lorem.sentence
user_id = spots + 1
spots = spots + 1
starts_at = DateTime.now + 1
Cposting.create!(
title: title,
content: content,
user_id: user_id,
spots: spots,
starts_at: starts_at
)
end
The migration looks like this, nothing special
class AddStartsAtToCpostings < ActiveRecord::Migration
def change
add_column :cpostings, :starts_at, :datetime
end
end
The problem is that starts_at after seeding is nil. Any idea why? Everything else gets inserted without problems. Also if I insert something manually in the database through the form it works, too.
Just use:
starts_at = Time.now
or,
starts_at = Time.now + 1
Update 1:
You can try this:
Change your migration to be like this:
class AddStartsAtToCpostings < ActiveRecord::Migration
def change_table
add_column :cpostings, :starts_at, :datetime
end
end
Use change_table method instead of change.
Update 2:
I just tested your migration locally. Your migration works fine and I can create objects from rails console using your migration and schema where start_at works fine if I use Time.now.

Why is my Rails migration "successfully" updating but not actually changing records?

Well this is a first. I'm trying to run a migration for my Rails app (v4.2.0), and while the migration is succeeding, it's not actually changing anything. Specifically, I'm trying to implement a counter_cache field for a table, assigning the start value for records that already have associations.
Here's my migration:
class AddCommentsCountToQuestions < ActiveRecord::Migration
def up
# dump SQL to console so I can see what's going on
ActiveRecord::Base.logger = Logger.new(STDOUT)
add_column :questions, :comments_count, :integer, null: false, default: 0
Question.reset_column_information
Question.find_each do |question|
puts "updating record #{question.id} to have #{question.comments.count} comments"
# use update! instead of update so that migration performs rollback on failure
question.update!(comments_count: question.comments.count)
puts "record #{question.id} actually persisted with #{question.reload.comments_count} comments"
end
end
def down
remove_column :questions, :comments_count
end
end
My console output demonstrates that upon reloading the record, it didn't persist the comments_count value:
updating record 1 to have 8 comments
record 1 actually persisted with 0 comments
updating record 2 to have 0 comments
record 2 actually persisted with 0 comments
updating record 3 to have 0 comments
And lastly, you can see that the SQL UPDATE command is not doing anything other than changing the updated_at column on the first record (with 8 comments), despite passing a comments_count value in my attributes hash:
D, [2015-02-13T09:15:54.997805 #68245] DEBUG -- : SQL (0.3ms) UPDATE "questions" SET "updated_at" = $1 WHERE "questions"."id" = $2 [["updated_at", "2015-02-13 16:15:54.992779"], ["id", 1]]
I'm making sure to call reset_column_information prior to updating any records, but it seems to have no effect. I've done this plenty of times in recent past (the past few days even) and am banging my head against the wall here.
I'm not sure why your version fails - it looks fine. Still, you might want to try the canonical version of populating counters:
Question.reset_counters(question.id, :comments)
in place of of update!

Create endtime from collection_select

Good Afternoon,
Feels like a newbie question but I have the following:
:start_datetime t.date
:end_datetime t.date
:length t.integer
On create my end_datetime is nil but I want to get it by adding the length to the start_datetime in order to generate the endtime.
Currently my integer is stored as '30 Mins', 30 and '1 Hour', 60.
Drawn a blank on where I should do this. I'm guessing I need to create it in the model when the booking is created.
If you're going to be using increments of minutes, I think you should start by redefining your datetimes as datetime rather than date.
then do something like this:
#controller
def create
...
end_datetime = params[:start_datetime] + params[:length].minutes
#save this
...
end

RoR: how to get the creation timestamp in the model

I have a class Event where I need a method that compares the current date to the date the Event was created. Can you tell me how to access the created_at timestamp the scaffold created for the Event database table?
class Event < ActiveRecord::Base
attr_accessible :location, :name
def isInsertedLongAgo
# current date - insertion date >= 90 days
end
end
Same as any other attribute - just call it:
def isInsertedLongAgo
# current date - insertion date >= 90 days
Time.now - created_at >= 90.days
end
Hi you can acces created at using created_at field self.created_at,
At the time of scaffold time stamp is created which create created_at,updated_at
You can directly access those variables.
replace insertion date with created_at

Rails 2 + SQL server: How to make table that is supposed to have multiple timestamps?

Hi I am currently working on a Rails 2 project that uses Microsoft SQL Server. I am about to implement the delayed_job gem, which allows background processes. In order to do this, I must create a table that would look like this in a migration:
class CreateDelayedJobs < ActiveRecord::Migration
def self.up
create_table :delayed_jobs, :force => true do |table|
table.integer :priority, :default => 0 # Allows some jobs to jump to the front of the queue
table.integer :attempts, :default => 0 # Provides for retries, but still fail eventually.
table.text :handler # YAML-encoded string of the object that will do work
table.text :last_error # reason for last failure (See Note below)
table.datetime :run_at # When to run. Could be Time.zone.now for immediately, or sometime in the future.
table.datetime :locked_at # Set when a client is working on this object
table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead)
table.string :locked_by # Who is working on this object (if locked)
table.timestamps
end
add_index :delayed_jobs, [:priority, :run_at], :name => 'delayed_jobs_priority'
end
def self.down
drop_table :delayed_jobs
end
end
Notice that there are 3 datetime columns. However, I must do this in pure SQL using SQL Server syntax. According to W3 schools:
timestamp Stores a unique number that gets updated every time a row gets created or modified. The timestamp value is based upon an internal clock and does not correspond to real time. Each table may have only one timestamp variable
CREATE TABLE delayed_jobs
{
id uniqueidentifier,
priority int,
attempts int,
handler text,
last_error text,
run_at timestamp,
locked_at timestamp,
failed_at timestamp,
locked_by varchar(255)
};
How can I add go around this single timestamp limitation?
How do I add indexes?
Just a heads-up, you're gonna get nailed for mentioning W3 Schools here. :-) It's an evil site. Anyway, you can have as many timestamp columns as you need. They can hold the system time or any other timestamp you want. There are no limitations.
For the indexes, use:
CREATE INDEX index_name
ON table_name (column_name)
OR
CREATE UNIQUE INDEX index_name
ON table_name (column_name)

Resources