View cause of rollback error in rails console - ruby-on-rails

I'm trying to update a record through the rails console and am getting a rollback error:
Project.find(118).update_attributes(:featured=>true)
Project Load (2.6ms) SELECT "projects".* FROM "projects" WHERE "projects"."id" = $1 LIMIT 1 [["id", 118]]
(2.8ms) BEGIN
(1.3ms) ROLLBACK
=> false
How can I view the source of the error? I'm able to update the attribute for other records, so I'd like to inspect why this particular record isn't working.

Your Project instance is probably invalid. To see what error prevented it from saving, you can type:
project = Project.find 118
project.assign_attributes(featured: true)
project.valid?
project.errors.full_messages

Related

Rails on Heroku - DB edits via console not saving

I have deployed my Rails application on Heroku. However, I cannot save DB edits via Heroku console.
If I want to update a model via the console I take the following steps -
rails console
#doc = Document.find_by_title('Test’)
#doc.status = 1
#doc.save*
However, in Heroku model saves do not work
heroku run rails c
#doc = Document.find_by_title('Test’)
#doc.status = 1
#doc.save
Console output is as follows
(1.9ms) BEGIN
(1.9ms) BEGIN
Commontator::Thread Load (1.7ms) SELECT "commontator_threads".* FROM "commontator_threads" WHERE "commontator_threads"."commontable_id" = $1 AND "commontator_threads"."commontable_type" = $2 LIMIT 1 [["commontable_id", 40], ["commontable_type", "Document"]]
Commontator::Thread Load (1.7ms) SELECT "commontator_threads".* FROM "commontator_threads" WHERE "commontator_threads"."commontable_id" = $1 AND "commontator_threads"."commontable_type" = $2 LIMIT 1 [["commontable_id", 40], ["commontable_type", "Document"]]
Approval Load (1.8ms) SELECT "approvals".* FROM "approvals" WHERE "approvals"."document_id" = $1 [["document_id", 40]]
Approval Load (1.8ms) SELECT "approvals".* FROM "approvals" WHERE "approvals"."document_id" = $1 [["document_id", 40]]
Review Load (1.8ms) SELECT "reviews".* FROM "reviews" WHERE "reviews"."document_id" = $1 [["document_id", 40]]
Review Load (1.8ms) SELECT "reviews".* FROM "reviews" WHERE "reviews"."document_id" = $1 [["document_id", 40]]
(2.1ms) ROLLBACK
(2.1ms) ROLLBACK
This is the same for any attribute I try to update.
Any ideas?
I think I figured it out. It was being affected by validations, if you want to save and skip validation, then
#document.update_columns(status: 1)
or
#document.attribute['status'] = 1
#document.save
Both will skip validation.
You can also try this.
heroku run rails c
doc = Document.find_by_title("Test")
doc.status = 1
doc.save(validate: false)

Weird output on all rails commands

I just recently started getting weird output whenever I run any command from the command line within my rails app. I did just add Devise to it a couple days ago so maybe that's the issue?
One example is this:
> rails g mailer UserMailer
[16:34:48] (0.1ms) BEGIN
User Exists (0.6ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('') LIMIT 1
(0.1ms) ROLLBACK
(0.1ms) BEGIN
User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('') LIMIT 1
(0.1ms) ROLLBACK
create app/mailers/user_mailer.rb
invoke haml
create app/views/user_mailer
invoke rspec
create spec/mailers/user_mailer_spec.rb
The unexpected output is ALWAYS some sort of SQL logging. Anyone know what would cause this?
The problem seems to be uniqueness validation. You have validate_uniqueness_of :email in your model and you are trying to create a new user with the same email, at least the error shows so.

creating seed data for a model not working

So I have a question model that belongs to User. Initially, I'd like to set basic questions with an attribute public: true, and every user can see this kind of questions which I'd like to create in the seed.rb.
Then, subsequently with an Answer model. Each users answer belongs to a certain question.
Now the issue is creating these pre-made questions for the users to answer I've tried the following in seed.rb:
u = User.new(email: "test#gmail.com", password: "testpass", password_confirmation: "testpass", gender: "M")
questions = u.questions.build(title: "What is your favourite food?")
u.save
And I'd like to call the same default questions for all users in the view with
questions_controller.rb
def index
#questions = Question.all
end
But this simply doesn't seem to be working, i.e. when I go to rails c and run u, it's an undefined method.. and the u.questions is an empty array. I've run these lines in console manually and they worked so I'm not sure what's happening here.
What am I doing wrong?
Update dev log
^[[1m^[[36mUser Load (16.9ms)^[[0m ^[[1mSELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1^[[0m
^[[1m^[[35mQuestion Load (645.9ms)^[[0m SELECT "questions".* FROM "questions" WHERE "questions"."user_id" = $1 [["user_id", 2]]
^[[1m^[[36mActiveRecord::SchemaMigration Load (48.4ms)^[[0m ^[[1mSELECT "schema_migrations".* FROM "schema_migrations"^[[0m
^[[1m^[[36mActiveRecord::SchemaMigration Load (1.0ms)^[[0m ^[[1mSELECT "schema_migrations".* FROM "schema_migrations"^[[0m
^[[1m^[[35m (0.3ms)^[[0m BEGIN
^[[1m^[[36mUser Exists (34.7ms)^[[0m ^[[1mSELECT 1 AS one FROM "users" WHERE "users"."email" = 'anthony#gmail.com' LIMIT 1^[[0m
^[[1m^[[35m (0.3ms)^[[0m ROLLBACK
DEPRECATION WARNING: You didn't set config.secret_key_base. Read the upgrade documentation to learn more about this new config option. (called from service a\
t /usr/local/rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/webrick/httpserver.rb:138)
I think the issue was that the OP had bad data in the development database.
Running rake db:drop db:create db:setup appeared to fix the issue.

accepts_nested_attributes_for runs before controller method

I'm having a baffling problem. I have a LineItem model that accepts nested attributes for a Trackable and a Product. I am overriding the default trackable_attributes= and product_attributes= methods to allow me to find or initialize records. For example:
def trackable_attributes=(attributes)
_trackable = Project.find_or_initialize_by_id(attributes.delete("id"))
_trackable.attributes = attributes
self.trackable = _trackable
end
When I post to the LineItemController#create, even when there's only a logging statement in it, it runs all of the posted parameters as if I'm trying to build/create a new line item. I don't have any before_filters that would be doing this on the #create method.
def create
logger.info("LineItemsController#create")
end
Webserver logs:
Started POST "/line_items" for 127.0.0.1 at 2013-04-10 14:02:13 -0700
Processing by LineItemsController#create as JS
Parameters: {"utf8"=>"✓", "authenticity_token"=>"MY_SECRET_TOKEN", "line_item"=>{"trackable_type"=>"Project", "tax_rate"=>"0", "price"=>"0.00", "provided_on_formatted"=>"Apr 10", "trackable_attributes"=>{"company_attributes"=>{"id"=>"87", "name"=>"Handmade Design"}, "id"=>"45", "name"=>"MEdia Blitz"}, "product_attributes"=>{"id"=>"75"}, "name"=>"Design", "notes"=>"Yellow", "quantity"=>"0.00", "unit_price"=>"205.0"}, "commit"=>"+"}
Person Load (0.3ms) SELECT "people".* FROM "people" WHERE "people"."id" = 73 LIMIT 1
(0.1ms) begin transaction
(0.4ms) UPDATE "people" SET "last_request_at" = '2013-04-10 21:02:13.861629', "perishable_token" = 'kzsB5dnCOHfykO1XMMi9', "updated_at" = '2013-04-10 21:02:13.863622' WHERE "people"."id" = 73
[paperclip] Saving attachments.
(1.2ms) commit transaction
Account Load (0.2ms) SELECT "accounts".* FROM "accounts" WHERE "accounts"."id" = 369 LIMIT 1
Person Load (0.3ms) SELECT "people".* FROM "people" WHERE "people"."account_id" = 369 ORDER BY id LIMIT 1
{"company_attributes"=>{"id"=>"87", "name"=>"Handmade Design"}, "id"=>"45", "name"=>"MEdia Blitz"}
Project Load (0.2ms) SELECT "projects".* FROM "projects" WHERE "projects"."id" = 45 LIMIT 1
Company Load (0.2ms) SELECT "companies".* FROM "companies" WHERE "companies"."id" = 87 LIMIT 1
trackable_attributes=(attributes)
trackable assigned
{"id"=>"75"}
Product Load (0.2ms) SELECT "products".* FROM "products" WHERE "products"."id" = 75 LIMIT 1
product_attributes=(attributes)
product assigned
LineItemsController#create
Notice that I have many logging statements scattered through my custom accepts_nested_attributes_for setters that are being called before the #create method even begins.
Is this normal? It seems to be causing problems with when I want to instantiate a new line_item the normal way in my LineItemsController#create method.
I'd really appreciate any help as I'm lost on where to start.

Spree/Rails user password reset

I'm trying to set user's (admin) password from Rails console:
bundle exec rails console
> Spree::User.first.email
=> "admin#mysite.com"
> Spree::User.first.encrypted_password
Spree::User Load (1.1ms) SELECT "spree_users".* FROM "spree_users" LIMIT 1
=> "4ec556............................................."
> Spree::User.first.password='spree123'
Spree::User Load (1.0ms) SELECT "spree_users".* FROM "spree_users" LIMIT 1
=> "spree123"
> Spree::User.first.password_confirmation='spree123'
Spree::User Load (1.0ms) SELECT "spree_users".* FROM "spree_users" LIMIT 1
=> "spree123"
> Spree::User.first.save!
Spree::User Load (1.0ms) SELECT "spree_users".* FROM "spree_users" LIMIT 1
(0.3ms) BEGIN
(1.3ms) SELECT COUNT(DISTINCT "spree_users"."id") FROM "spree_users" LEFT OUTER JOIN "spree_roles_users" ON "spree_roles_users"."user_id" = "spree_users"."id" LEFT OUTER JOIN "spree_roles" ON "spree_roles"."id" = "spree_roles_users"."role_id" WHERE "spree_roles"."name" = 'admin'
(0.3ms) COMMIT
=> true
> Spree::User.first.encrypted_password
Spree::User Load (1.0ms) SELECT "spree_users".* FROM "spree_users" LIMIT 1
=> "1bc15d.............................................."
So far so good. It looks like the new password for the user has been changed and commited to the database. However when I try to log in later with a web client and using the new password, it fails with invalid identity/password message.
I even tried to update password with Spree::User.first.reset_password!('spree123', 'spree123') but sill cann't sign in.
Rails 3.2.12
Spree 1.3.2
Any idea what am I doing wrong ? How to properly set a new password ?
Thanks.
The problem is that every time you're doing Spree::User.first it's reloading the record from the database. This means you are setting the value on one instance of the record, reloading it, and then saving the reloaded model that hasn't actually changed. An easy way around this is to create a local instance variable containing the record and update that instead:
user = Spree::User.first
user.password='spree123'
user.password_confirmation='spree123'
user.save!
Spree::User.first.update_attributes(password: 'password')

Resources