Devise login validation failure - validation

I rails3.0.4 and devise installed with following users table
create_table "users", :force => true do |t|
t.string "login"
t.string "email"
t.string "crypted_password", :null => false
t.string "password_salt", :null => false
t.string "persistence_token", :null => false
t.string "single_access_token", :null => false
t.string "perishable_token", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.string "database_authenticatable", :null => false
t.string "recoverable"
t.string "rememberable"
t.string "trackable"
t.string "reset_password_token"
end
The users table was not created by devise but I added the necessary
columns in migration.
And following settings in config/initializers/devise.rb
config.authentication_keys = [ :email]
But every time I try to sign up as a new user it throws:
2 errors prohibited this user from being saved:
Login is too short (minimum is 3 characters)
Login should use only letters, numbers, spaces, and .-_# please.
Any ideas why it could happen?

Yes, the login is too short and/or contains the wrong characters :)
You enabled the devise built-in validations, and that's what they validate. To use your own validations remove :validatable from your devise inclusion in app/models/user.rb
If you're interested, the validation used by devise is defined in lib/devise/models/validatable.rb in the devise gem.
Should the validation not be the problem you'll have to show the log of a user creation request, so that we can see what parameters are submitted.
EDIT: Oh I see, I misread - it's about "login". Well, see comments below.

Related

Ancestry gem gives error "The scope body needs to be callable." in rails 4?

models/message.rb
class Message < ActiveRecord::Base
has_ancestry
end
schema.rb
create_table "messages", force: :cascade do |t|
t.text "content"
t.integer "parent_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "ancestry"
end
after adding has_ancestry in model it gives error Argument Error.
"The scope body needs to be callable."
Please help me
Thanks

ActiveRecord::StatementInvalid at /category/5

I am a new developer working on a Sinatra/Ruby/ActiveRecord app. I have established a 1:many (postgres) relationship between Category and Recipe. When I try to list the recipes in a category I get the error:
ActiveRecord::StatementInvalid at /category/5
PG::UndefinedColumn: ERROR: column recipes.category_id does not exist LINE 1: SELECT 1 AS one FROM "recipes" WHERE "recipes"."category_id... ^ : SELECT 1 AS one FROM "recipes" WHERE "recipes"."category_id" = $1 LIMIT 1
file: postgresql_adapter.rb location: prepare line: 637
app.rb
get('/category/:id') do
#category = Category.find(params.fetch('id'))
#recipes = #category.recipes
erb(:category)
end
category.erb
<% if #recipes.any?() %>
<% #recipes.each() do |recipe| %>
<ul>
<li><a href='/recipe/<%=recipe.id%>'> <%=recipe.recipe_name%></a></li>
</ul>
<%end%>
<%else %>
<p>You have no recipes!</p>
<%end%>
schema
ActiveRecord::Schema.define(version: 20150930234556) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "categories", force: :cascade do |t|
t.string "cat_name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "images", force: :cascade do |t|
t.string "image_name"
t.string "url"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "alt"
t.integer "width"
t.integer "height"
t.integer "recipe_id"
end
create_table "ingredients", force: :cascade do |t|
t.string "ingredient_name"
t.integer "recipe_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "instructions", force: :cascade do |t|
t.string "instruction_name"
t.integer "recipe_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "recipes", force: :cascade do |t|
t.string "recipe_name"
t.string "source"
t.string "servings"
t.string "comment"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "cat_id"
end
end
I have searched my project folders and cannot find category_id. Don't know why it's looking for that, my field names are category.id and recipe.cat_id.
This:
#recipes = #category.recipes
suggests that you have
has_many :recipes
in your Category model. That has_many will be looking for a category_id column in your recipes table (i.e. a category_id attribute in your Recipe model). But you don't have a recipes.category_id column, you have a recipes.cat_id column:
create_table "recipes", force: :cascade do |t|
#...
t.integer "cat_id"
end
I'd recommend renaming the recipes.cat_id column to recipes.category_id to match the conventions that Rails has a very strong preference for. If you can't rename the column then add a :foreign_key option to that has_many to tell Category how to resolve the relationship:
has_many :recipes, :foreign_key => :cat_id

Friendly with existing Rails 4 app: No change

I have an existing app with devise running. User and log in and out etc. Thought I would like to get localhost:3000/users/15 changed to localhost:3000/users/ruby-boy so I have installed https://github.com/norman/friendly_id
I have ran rails generate friendly_id but when I ran rails generate scaffold user name:string slug:string:uniq, it say I already got a user.rb file so ok I've added: rails g migration AddSlugToUser slug:string:uniq and rails g migration AddNameToUser name:string. So I've added those two columns to my users table.
In my controllers I've replaced:
User.find(params[:id])
with:
User.friendly.find(params[:id])
Then ran this in console (rails c)
User.find_each(&:save)
But User.find_each(&:save) gave:
(0.1ms) commit transaction
(0.0ms) begin transaction
=> nil
I think I've followed the docs "eye for eye". Have I missed anything as the links wont change.
PS: I have edited the user.rb per website on github.
My user.rb:
class User < ActiveRecord::Base
extend FriendlyId
friendly_id :name, use: :slugged
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
belongs_to :plan
has_one :profile
attr_accessor :stripe_card_token
def save_with_payment
if valid?
customer = Stripe::Customer.create(description: email, plan: plan_id, card: stripe_card_token)
self.stripe_customer_token = customer.id
save!
end
end
end
Schema for users table:
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
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.datetime "created_at"
t.datetime "updated_at"
t.integer "plan_id"
t.string "stripe_customer_token"
t.string "slug"
t.string "name"
end
Add :name to your sign up form and then validate for uniqueness in your User model
Class User
validates :name, uniqueness: true
This way same name can't be created more than once and you'll avoid avoid weird slugs.

SQLite3::SQLException: duplicate column name: User_id: ALTER TABLE "comments" ADD "User_id" integer/

I ran the command
rails g migration AddUser_idToComments User_id:string
and then I figured out that User_id should be an integer and so I ran
rails g migration AddUser_idToComments User_id:integer --force thinking that it would overwrite the initial command.
But now, I'm getting this error:
```
louismorin$ rake db:migrate
== 20140910155248 AddIndexToComments: migrating ===============================
-- add_column(:comments, :Index, :string)
-> 0.0069s
== 20140910155248 AddIndexToComments: migrated (0.0070s) ======================
== 20140910181022 AddUserIdToComments: migrating ==============================
-- add_column(:comments, :User_id, :integer)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
SQLite3::SQLException: duplicate column name: User_id: ALTER TABLE "comments" ADD "User_id" integer/Users/louismorin/code/CP299/db/migrate/20140910181022_add_user_id_to_comments.rb:3:in change'
ActiveRecord::StatementInvalid: SQLite3::SQLException: duplicate column name: User_id: ALTER TABLE "comments" ADD "User_id" integer
/Users/louismorin/code/CP299/db/migrate/20140910181022_add_user_id_to_comments.rb:3:inchange'
SQLite3::SQLException: duplicate column name: User_id
/Users/louismorin/code/CP299/db/migrate/20140910181022_add_user_id_to_comments.rb:3:in `change'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
```
Here's my schema.rb file
```
ActiveRecord::Schema.define(version: 20140910155210) do
create_table "comments", force: true do |t|
t.text "body"
t.integer "post_id"
t.datetime "created_at"
t.datetime "updated_at"
t.string "User_Id"
end
add_index "comments", ["post_id"], name: "index_comments_on_post_id"
create_table "posts", force: true do |t|
t.string "title"
t.text "body"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "user_id"
t.integer "topic_id"
end
add_index "posts", ["topic_id"], name: "index_posts_on_topic_id"
add_index "posts", ["user_id"], name: "index_posts_on_user_id"
create_table "topics", force: true do |t|
t.string "name"
t.boolean "public", default: true
t.text "description"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "users", force: true do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
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.string "confirmation_token"
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.string "unconfirmed_email"
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
t.string "role"
t.string "avatar"
t.string "Image"
end
add_index "users", ["email"], name: "index_users_on_email", unique: true
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
```
Because of the error, your second migration -- changing the column type -- didn't run. If that migration was only intended to change that one column, we could then delete the file it generated and try again.
If you don't yet have any data in that column that you care about, that's pretty easy:
rails g migration ChangeTypeOfUserIdOnComments
This migration name isn't special. Might as well have been DoWhateverIWant
Then, edit the created migration's change method to something like this:
def change
remove_column :comments, :user_id
add_column :comments, :user_id, :integer
add_index :comments, :user_id
end
When you then run your un-run migrations rake db:migrate, it shouldn't trip up on the one which errored (because we deleted it), and then it should run this one, which removes the column and adds it back with the correct type.
If you DO have data you want to save, the procedure is more complicated. Your change method would have to grab the current user_id's for each comment, and then assign them to the new comments when we create the new column. The below should hopefully work:
def change
user_ids = {}
Comment.find_each{ |c| user_ids[c.id] = c.user_id.to_i }
remove_column :comments, :user_id
add_column :comments, :user_id, :integer
add_index :comments, :user_id
Comment.each{ |c| c.update_attribute(:user_id, user_ids[c.id])
end
Also note that the names of the migration in the command are generally all CamelCase or all snake_case. So: AddColumnUserIdToComments or add_column_user_id_to_comments. Naming as you did might cause problems.
** EDIT **
Modify a Column's Type in sqlite3
It appears that SQLite has NO good way to modify/drop a column. I'd suggest either:
Dropping and restarting a SQLITe table
Drop the table, drop the original user_id migration and the line in the new one about removing the old user_id column, and then create a new table with the new migrations. Should work fine if you don't care about your data
Switching to Postgres, which is the database Heroku uses.
It's probably a good idea (because you want your production and local databases to behave identically), but can be bug-prone to switch to.
Look here for guidance -- Change from SQLite to PostgreSQL in a fresh Rails project

Authlogic - how to check if a user is logged out

This is my setup:
user.rb
acts_as_authentic do |c|
c.logged_in_timeout(1.minutes)
end
user_session.rb
def to_key
new_record? ? nil : [ self.send(self.class.primary_key) ]
end
self.logout_on_timeout = true
application_controller.rb
helper_method :current_user_session, :current_user
private
def current_user_session
logger.debug "ApplicationController::current_user_session"
return #current_user_session if defined?(#current_user_session)
#current_user_session = UserSession.find
end
def current_user
logger.debug "ApplicationController::current_user"
return #current_user if defined?(#current_user)
#current_user = current_user_session && current_user_session.user
end
def require_user
logger.debug "ApplicationController::require_user"
unless current_user
#store_location
flash[:warning] = "You must be logged in to access this page"
#redirect_to new_user_session_url
redirect_to root_url
return false
end
end
def require_no_user
logger.debug "ApplicationController::require_no_user"
if current_user
#store_location
flash[:warning] = "You must be logged out to access this page"
redirect_to account_url
return false
end
end
But when I load my page, I will get the error
undefined method `logged_out?' for #<User:0x00000103ee8348>
I try to read the official GitHub page of Authlogic, but I still don't know, what I miss... Could anyone give me a tip for fix it?
Many thanks in advance!
I was having the exact same problem, and it boiled down to the fact I didn't have all of the necessary columns in my User model.
My original User model (from db/schema.rb) was pretty minimalistic:
create_table "users", :force => true do |t|
t.string "username"
t.string "name"
t.string "crypted_password"
t.string "password_salt"
t.string "persistence_token"
t.string "perm", :default => "employee"
end
However, I added the column t.datetime :last_requested_at to my model, as well as a few others that may or may not be needed. My final User model looks like:
create_table "users", :force => true do |t|
t.string "username"
t.string "name"
t.string "crypted_password"
t.string "password_salt"
t.string "persistence_token"
t.string "perm", :default => "employee"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "login_count", :default => 0, :null => false
t.integer "failed_login_count", :default => 0, :null => false
t.datetime "last_request_at"
t.datetime "current_login_at"
t.datetime "last_login_at"
t.string "current_login_ip"
t.string "last_login_ip"
end
After adding in the other columns, I no longer get the undefined method 'logged_out?'... error.
Good luck!
(reference/more info: http://www.michaelhamrah.com/blog/2009/05/authlogic-and-openid-on-rails/ -- search in the page for logged_out?, the explanation was about 3/4 of the way down the post.)
If you want to know if a user is logged out, you can do:
if current_user_session
...
This condition will return true if the user is logged in (there is a session), and false if they are logged out (the session is nil).
As for the error message, undefined method 'logged_out?' for #<User:0x00000103ee8348> means that you haven't defined a method called logged_out?, so it doesn't know what you mean.
Authlogic doesn't define a logged_out? method for the User model, and neither have you, so there's nothing to call. The reason is that the state of either being "logged in" or being "logged out" doesn't have anything to do with the User model, but instead is a property of whether or not a given user has an active UserSession record.

Resources