Why does my users table have a no column error? - sql

I am getting the following error after running my tests in the console:
ActiveRecord::StatementInvalid: SQLite3::SQLException: table users has no column named password: INSERT INTO "users"
user_test.rb:
class UserTest < ActiveSupport::TestCase
test "a user should enter a first name" do
user = User.new
assert !user.save
assert !user.errors[:first_name].empty?
end
test "a user should enter a last name" do
user = User.new
assert !user.save
assert !user.errors[:last_name].empty?
end
test "a user should enter a profile name" do
user = User.new
assert !user.save
assert !user.errors[:profile_name].empty?
end
test "a user should have a unique profile name" do
user = User.new
user.profile_name = users(:adam).profile_name
assert !user.save
assert !user.errors[:profile_name].empty?
end
end
users.rb:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me,
:first_name, :last_name, :profile_name
validates :first_name, presence: true
validates :last_name, presence: true
validates :profile_name, presence: true,
uniqueness: true
has_many :statuses
def full_name
first_name + " " + last_name
end
end
users.yml:
dan:
first_name: "Dan"
last_name: "Can"
email: "dan#email.com"
profile_name: "dan"
password: "123456"
password_confirmation: "123456"
database.yml:
# SQLite version 3.x
# gem install sqlite3
#
# Ensure the SQLite 3 gem is defined in your Gemfile
# gem 'sqlite3'
development:
adapter: sqlite3
database: db/development.sqlite3
pool: 5
timeout: 5000
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
adapter: sqlite3
database: db/test.sqlite3
pool: 5
timeout: 5000
production:
adapter: sqlite3
database: db/production.sqlite3
pool: 5
timeout: 5000
What I believe to be my user migrate file:
class DeviseCreateUsers < ActiveRecord::Migration
def change
create_table(:users) do |t|
t.string :first_name
t.string :last_name
t.string :profile_name
## Database authenticatable
t.string :email, :null => false, :default => ""
t.string :encrypted_password, :null => false, :default => ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
t.integer :sign_in_count, :default => 0
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
t.string :last_sign_in_ip
## Confirmable
# t.string :confirmation_token
# t.datetime :confirmed_at
# t.datetime :confirmation_sent_at
# t.string :unconfirmed_email # Only if using reconfirmable
## Lockable
# t.integer :failed_attempts, :default => 0 # Only if lock strategy is :failed_attempts
# t.string :unlock_token # Only if unlock strategy is :email or :both
# t.datetime :locked_at
## Token authenticatable
# t.string :authentication_token
t.timestamps
end
add_index :users, :email, :unique => true
add_index :users, :reset_password_token, :unique => true
end
end
I would like to know what is causing the error, but more importantly why.

When I removed the password and password_confirmation columns from the users fixture it passed the test with no errors. I'm told by a friend that is was likely due to an upgrade in devise.

It seems to me that the problem you have is, just as the error says, there is no password column in your User table. You have to add it to your migration:
t.string :password
Note, however, that I have never used Devise so I may be wrong about this.

I think there are a couple of possibilities here but I will focus on the immediate problem. If your Rake tasks are returning No command found, then it may be because Rake isn't installed on your computer. I would start there.
To install Rake, type in your terminal:
gem install rake
The reason why your code doesn't work is because your users table doesn't have a column named password. With rake db:migrate and rake db:test:prepare you are ensuring that any migrations you created are applied to your database.
Let me know the results.

Related

Rails - Saving Objects with NOT NULL constraint

I have a model called Issue that has the following database structure :
class CreateIssues < ActiveRecord::Migration
def change
create_table :issues do |t|
t.string :path, null: false
t.string :filename, null: false
t.string :name, null: false
t.string :year
t.integer :number
t.timestamps null: false
end
end
end
In my model tests, I use the following line :
issue = Issue.create path: "test_path", filename: "test_filename", name: "test_name"
... which raises an exception when saving :
SQLite3::ConstraintException: NOT NULL constraint failed:
issues.path: INSERT INTO "issues" ("created_at", "updated_at") VALUES (?, ?)
From what I understand, when calling create or new/save, rails starts by inserting an entry with only the timestamps. I would expect the insert to contain all of the values that I have passed to the create method. Am I missing a step in the creation process?
EDIT :
Basic information and steps:
Using SQLite3
Using Rails 4.2.1
Using RSpec
Generated the Issue model using be rails generate model Issue
Added the NULL constraints afterwords by hand
Did be rake db:migrate successfully
Tried my code in various model spec files
Tried other models, I get generated SQL that only includes the timestamps.
EDIT 2:
Here is my Issue model :
class Issue < ActiveRecord::Base
has_one :pending_issue
has_one :watched_issue
has_many :unmatched_issues
validates :path, presence: true
validates :filename, presence: true
validates :name, presence: true
attr_accessor :path
attr_accessor :filename
attr_accessor :name
attr_accessor :year
attr_accessor :number
end
Your result is anomalous. This is what I get:
# migration
class CreateIssues < ActiveRecord::Migration
def change
create_table :issues do |t|
t.string :path, null: false
t.timestamps null: false
end
end
end
Then in the console:
Issue.create path: "path"
# (0.1ms) begin transaction
# SQL (0.3ms) INSERT INTO "issues" ("path", "created_at", "updated_at") VALUES (?, ?, ?) [["path", "path"], ["created_at", "2015-06-21 16:55:08.304653"], ["updated_at", "2015-06-21 16:55:08.304653"]]
# (0.8ms) commit transaction
# => #<Issue id: 1, path: "path", created_at: "2015-06-21 16:55:08", updated_at: "2015-06-21 16:55:08">
My test:
require "test_helper"
describe Issue do
it "can be created" do
Issue.create path: "test_path"
end
end
passes. No exception.
What I think may have happened is that your database schema has become out of date on your test database.
Firstly, does a similar 'create' work in the development (default) rails console? If so, it's a big indication that something is very different in your test and development environments.
What happens if you force the console to use the test environment?
RAILS_ENV=test rails c
Does it work here?
I think you may need to manually rollback your test database to the migration which first created your issues table, then re-migrate
RAILS_ENV=test rake db:rollback
Keep applying until you reach the appropriate migration, then:
RAILS_ENV=test rake db:migrate
Does that help?
EDIT:
This appears to be the issue:
attr_accessor :path
attr_accessor :filename
attr_accessor :name
attr_accessor :year
attr_accessor :number
These will overwrite the Rails default accessors, at a guess. They are certainly not needed.
Did you accidentally omit attr_accessible for :path?

undefined method `zero?' for nil:NilClass on Devise

I'm installing Devise and I'm getting a undefined method `zero?' for nil:NilClass when trying to register a new user. Routing seams ok, as other pages such as sign in, sign up, lost password is showing up.
The error message:
NoMethodError in Devise::RegistrationsController#create
undefined method `zero?' for nil:NilClass
My Class User is as follows:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable #, :encryptable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me, :password_salt
# attr_accessible :title, :body
end
The migration is running OK as:
class DeviseCreateUsers < ActiveRecord::Migration
def change
create_table(:users) do |t|
## Database authenticatable
t.string :email, :null => false, :default => ""
t.string :encrypted_password, :null => false, :default => ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
t.integer :sign_in_count, :default => 0
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
t.string :last_sign_in_ip
## Confirmable
t.string :confirmation_token
t.datetime :confirmed_at
t.datetime :confirmation_sent_at
t.string :unconfirmed_email # Only if using reconfirmable
## Lockable
t.integer :failed_attempts, :default => 0 # Only if lock strategy is :failed_attempts
t.string :unlock_token # Only if unlock strategy is :email or :both
t.datetime :locked_at
## Token authenticatable
t.string :authentication_token
t.string :password_salt
t.timestamps
end
add_index :users, :email, :unique => true
add_index :users, :reset_password_token, :unique => true
add_index :users, :confirmation_token, :unique => true
add_index :users, :unlock_token, :unique => true
add_index :users, :authentication_token, :unique => true
end
end
Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"MNwIeldQzcBbakbcLkbcIlNYiKQ72F3nJyqHOsDdRoM=",
"user"=>{"email"=>"email#example.com",
"password"=>"[FILTERED]",
"password_confirmation"=>"[FILTERED]"},
"commit"=>"Sign up",
"locale"=>"en"}
Devise Version:
2.1.2
Ruby version:
ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-darwin12.3.0]
Rails version:
Rails 3.2.13

cant mass assign the protected attributes

iam working in rails 3.while trying to creating a user i am getting
cant mass assign the protected attributes error
I included following gems in the gemfile
gem 'authlogic'
gem 'gemcutter'
and run bundle install in rails console
then create a a user model and add the required authlogic columns to the migration.
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :login, :null => false
t.string :crypted_password, :null => false
t.string :password_salt, :null => false
t.string :persistence_token, :null => false
t.timestamps
end
end
end
and did rake db:migrate
Included authlogic in the user model.
# /app/models/user.rb
class User < ActiveRecord::Base
acts_as_authentic
end
while trying to create a user in rails console User.create(name: "pria",password: "priya123", password_confirmation: "priya123")
iam getting
cant mass assign the protected attributes :name, :password, :password_confirmation
How can i rectify this error!
In your User model:
attr_accessible :name, :password, :password_confirmation
You must add these attributes to the attr_accessible list in your model.
For important information about mass-assignment and its security implications: http://guides.rubyonrails.org/security.html#mass-assignment

Can we use refinerycms for user authentication purpose

Am developing one website for which I have to do user login and registration form for the authentication purpose. My question is can we do this using only refinerycms and if it is possible please tell me how to do this. If it is not possible then please tell me which is the best approach. Am trying to implement user authentication using refinerycms. Am new to refinerycms.
Refinery uses devise so you can use that as well. You can create a model that might look something like this:
module Refinery
module Partners
class Partner < Refinery::Core::BaseModel
self.table_name = 'refinery_partners'
acts_as_indexed :fields => [:name]
validates :email, :presence => true, :uniqueness => true
#devise methods
devise :database_authenticatable, :recoverable, :rememberable, :trackable,:validatable, :authentication_keys => [:email]
end
end
end
and not to forget the migration:
class CreatePartnersPartners < ActiveRecord::Migration
def up
create_table :refinery_partners do |t|
t.string :email
t.string :name
## Database authenticatable
t.string :encrypted_password, :null => false, :default => ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
t.integer :sign_in_count, :default => 0
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
t.string :last_sign_in_ip
t.timestamps
end
end
def down
if defined?(::Refinery::UserPlugin)
::Refinery::UserPlugin.destroy_all({:name => "refinerycms-partners"})
end
if defined?(::Refinery::Page)
::Refinery::Page.delete_all({:link_url => "/partners/partners"})
end
drop_table :refinery_partners
end
end
This should create the basic model that you can use. To finish up, change the routes.rb in your extension to add devise routes:
devise_for :partners, :class_name => "Refinery::Partners::Partner",
:controllers => {:sessions => 'refinery/partners/sessions', :passwords => 'refinery/partners/passwords'}
and override refinery/partners/passwords_controller.rb
module Refinery
module Partners
class PasswordsController < Devise::PasswordsController
end
end
end
and refinery/partners/sessions_controller.rb
module Refinery
module Partners
class SessionsController < Devise::SessionsController
end
end
end
now you should have everything you need

ActiveAdmin and Carrierwave with :has_many

I'm getting totally crazy right now.
I have 2 models: project and screenshot:
create_table "projects", :force => true do |t|
t.string "name"
t.text "description"
t.boolean "isactive"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "slug"
t.string "logo"
t.string "teaser"
end
add_index "projects", ["slug"], :name => "index_projects_on_slug"
create_table "screenshots", :force => true do |t|
t.integer "project_id"
t.string "image"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
Project model looks like
class Project < ActiveRecord::Base
attr_accessible :name, :description, :isactive, :slug, :logo, :teaser, :screenshots_attributes
scope :isactive, :conditions => ["isactive = ?",true]
mount_uploader :logo, LogoUploader
extend FriendlyId
friendly_id :name, use: [:slugged, :history]
has_many :screenshots
accepts_nested_attributes_for :screenshots
end
and the screenshot model
class Screenshot < ActiveRecord::Base
belongs_to :project, :polymorphic => true
mount_uploader :screenshots, ScreenshotUploader
end
Screenshot Uploader is unedited currently:
# encoding: utf-8
class ScreenshotUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
# include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
storage :file
# storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# Provide a default URL as a default if there hasn't been a file uploaded:
# def default_url
# "/images/fallback/" + [version_name, "default.png"].compact.join('_')
# end
# Process files as they are uploaded:
# process :scale => [200, 300]
#
# def scale(width, height)
# # do something
# end
# Create different versions of your uploaded files:
# version :thumb do
# process :resize_to_fit => [300, 150]
# end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
# def extension_white_list
# %w(jpg jpeg gif png)
# end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
# def filename
# "something.jpg" if original_filename
# end
end
And now I'm trying to add screenshots from activeadmin using this form
form do |f|
f.inputs "Project Details" do
f.input :name
f.input :logo, :as => :file, :hint => f.template.image_tag(f.object.logo.url)
f.input :teaser
f.input :description
f.input :isactive
f.has_many :screenshots do |s|
s.input :image, :as => :file
end
end
f.buttons
end
But all I get is:
NoMethodError (undefined method `screenshots_changed?' for #<Screenshot:0xc940cd0>):
I played around with this for the last hours but nothing I tried worked :(
Any suggestions?
I believe the default active_admin form do |f| needs to be replaced with:
form(:html => { :multipart => true }) do |f|
You need to uncomment this line # include CarrierWave::RMagick
I had the same problem. Make sure you ran the migration (rake db:migrate)