Unknown attribute rails 4 - ruby-on-rails

im new into Rails 4 development and rails in general. I red official "getting started with rails" guide where it is shown how to create blog. So I want to do my own from 0 registration, auth system.
While creating new user I get this error. I do not understand what I am doing wrong. Any advice?
Git repo:
https://github.com/pumpurs/auth
ActiveRecord::UnknownAttributeError in UsersController#create
unknown attribute: password
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new(params[:user].permit(:password, :email, :password_confirmation))
end
private
def user_params
params.require(:user).permit(:password, :email, :password_confirmation)
end
end
Model file:
class User < ActiveRecord::Base
before_save :encrypt_password
validates_confirmation_of :password
validates_presence_of :password, :on => :create
validates_presence_of :email
validates_uniqueness_of :email
def enrypt_password
if password.present?
self.password_salt = BCript::Engine.generate_salt
self.password_hash = BCript::Engine.generate.hash_seret(password, password_salt)
end
end
end

You need to add attr_accessor :password to your User model, to provide a non-db-backed attribute to use to base your db-backed password_hash attribute off of.

Related

Setting a basic entity while creating a new user in Devise

Im using Devise to create my users in an App with Ruby on Rails.
I have a User model that has a Plan (hobby,premium, etc...)
When creating a new user, I want to add the basic plan to this new user (for business rules needs, I cant leave it blank).
The question is, how can I add this plan when creating this new user?
Here is my controller:
class RegistrationsController < Devise::RegistrationsController
clear_respond_to
respond_to :json
def save_user_type
session[:user_type] = params[:user_type]
end
private
def sign_up_params
params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation, :type, :provider )
end
end
In which method should I add something like this?
#user.plan = Plan.first
#user.save
class User < ActiveRecord::Base
has_one :plan
after_create :build_default_plan
private
def build_default_plan
plan.create(#paln_params)
#.. so on
end
end
Added this line to the user model
after_create do |user|
user.plan = Plan.first
user.save
end

One Model and two controller validation Ruby on Rails?

One thing that confuses me the most is when doing validation in one model with two controllers. I have a login system which register and logs users in. There both use the same model but both does not use the same amount of HTML widgets. One controller contains password, retype password, user name, first & second name and so on. The second controller uses only the user name and password fields. How would you do validation in the same model for this situation?
Thank you
here is the controller that register new users:
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
session[:user_id] = #user.id
redirect_to '/cool'
else
#user = Newuser.new
#user.valid?
#user.errors.messages
render 'new'
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password, :salt, :firstname, :secondname, :address, :postcode)
end
end
second controller:
class LoginsController < ApplicationController
before_filter :authorize
def index
#rentals = Rental.where(user_id: current_user.id).limit(5)
#buys = Buy.where(user_id: current_user.id).limit(5)
#users = User.where(id: current_user.id)
#buyGames = BuyGame.where(user_id: current_user.id).limit(5)
end
def destroy
#user = User.find(params[:id])
#user.destroy
redirect_to '/logout'
end
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
if #user.update(account_params)
redirect_to '/cool'
else
render 'edit'
end
end
private
def account_params
params.require(:user).permit(:name, :email, :password, :salt, :firstname, :secondname, :address, :postcode)
end
end
Here is my model:
class User < ApplicationRecord
has_secure_password
end
One way to go is to remove validations from the model and put them in form objects. For this case, you'll have two form objects, each with its own set of validations. And you use the appropriate one in respective controllers. Something along these lines:
# logins_controller
def update
login_form = FormObjects::LoginForm.new(login_params)
if login_form.valid?
redirect_to '/cool'
else
render 'edit'
end
end
# users controller
def create
signup_form = FormObjects::SignupForm.new(user_params)
if signup_form.save
redirect_to '/cool'
else
render 'new'
end
end
# signup_form
module FormObjects
class SignupForm
include ::ActiveMode::Model
validate_presense_of :email, :password, :password_confirmation, :address, :whatever_else
def save
# create user here
end
end
end
# login_form
module FormObjects
class LoginForm
include ::ActiveMode::Model
validate_presense_of :email, :password
end
end
You can simply specify validations on actions, that is:
validates :first_name, presence: true, on: :create # which won't validate presence of first name on update or any other action
I believe the trick you are looking for is to define validation actions on create/update of the model. Something roughly along these lines:
class User < ActiveRecord::Base
# These are example validations only; replace with your actual rules.
validates :password, confirmation: true
validates_presence_of :username
validates :first_name, presence: true, format: {with: /.../}, on: create
validates :last_name, presence: true, format: {with: /.../}, on: create
end
...However, I am unclear why you would want to do this in your specific example. It would be advisable to always run all validation checks on fields like first_name, to help maintain data integrity.

Rails password can't be blank error

I am trying to create a user signup form in Rails 4.1.6. I keep getting a 'password can't be blank' error. I can see that both the password and password_confirmation are in the params hash but not in the params[:user] sub-hash. I cannot figure out why for the life of me. Any help will be greatly appreciated.
User Model:
class User < ActiveRecord::Base
belongs_to :company
has_secure_password
end
Users Controller:
class UsersController < ApplicationController
respond_to :json
def index
#users = User.all
respond_with(#users)
end
def create
#user = User.new(user_params)
#user.save
respond_with(#user)
end
private
def user_params
params.require(:user).permit(:given_name, :family_name, :email, :password, :password_confirmation)
end
end
It sounds like your parameters are not being sent to the server correctly.
password should be sent as user[password] and password_confirmation should be sent as user[password_confirmation].
See documentation for hash and array parameters.
Alternatively, adding wrap_parameters to the controller will wrap parameters into a nested hash.
wrap_parameters :user, include: [:given_name, :family_name, :email, :password, :password_confirmation]
See documentation for ActionController::ParamsWrapper.

authentication fails after submiting - rails 4

I am trying to make simple authentication/registration ruby app. I am using BCrypt gem for crypting and it now gives me some problems. When I press submit button it throws
undefined method `password_salt=' for #<User:0x007f93c36bc570>
Ok, so I red that this code should be places from model to coontroler, but that gave me this er
undefined local variable or method `encrypt_password' for #<User:0x007f93c5f35f10>
I have tried rake db:migrate and restarting app also
git repo: https://github.com/pumpurs/auth
(code im talking about)
def encrypt_password
if password.present?
self.password_salt = BCrypt::Engine.generate_salt
self.password_hash = BCrypt::Engine.hash_secret(password, password_salt)
end
end
controller:
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new(params[:user].permit(:password, :email, :password_confirmation))
if #user.save
redirect_to root_url, :notice => "Signed up!"
else
render "new"
end
end
private
def user_params
params.require(:user).permit(:password, :email, :password_confirmation)
end
end
model file:
class User < ActiveRecord::Base
attr_accessor :password, :salt
before_save :encrypt_password
validates_confirmation_of :password
validates_presence_of :password, :on => :create
validates_presence_of :email
validates_uniqueness_of :email
def encrypt_password
if password.present?
self.password_salt = BCrypt::Engine.generate_salt
self.password_hash = BCrypt::Engine.hash_secret(password, password_salt)
end
end
end
Add
attr_accessor :password_salt
in model?
Why don't use Devise or another authentication gem?

Rails Scaffold destroy not working as expected

I was adding uniqueness validation to the model in charge of user registration. The username should be uniqueness.
I created a user when testing some days ago, lets call it "example-guy". Then I deleted him from the scaffolding user interface and now when trying to register a new user as "example-guy", it returns that the name has already been taken.
So how can I fix this from the DB without reverting to its "birth-state" and modify the controller to actually destroy the table entry?
Or maybe Rails is keeping track of what was writed to DB, even after destruction?
Im using omniauth-identity, the user model:
class User < ActiveRecord::Base
attr_accessible :name, :provider, :uid, :email
# This is a class method, callable from SessionsController
# hence the "User."
def User.create_with_omniauth(auth)
user = User.new()
user.provider = auth["provider"]
user.uid = auth["uid"]
user.name = auth["info"]["name"]
# ADD EMAIL
user.email = auth["info"]["email"]
user.save
return user
end
end
User controller's destroy function:
# DELETE /users/1
# DELETE /users/1.json
def destroy
#user = User.find(params[:id])
#user.destroy
respond_to do |format|
format.html { redirect_to users_url }
format.json { head :no_content }
end
end
end
Validations are made trought "Identity" model inherited from omniauth's active record:
class Identity < OmniAuth::Identity::Models::ActiveRecord
attr_accessible :email, :name, :password_digest, :password, :password_confirmation
#attr_accessible :email, :name, :password_digest :password, :password confirmation
validates_presence_of :name
validates_uniqueness_of :name
validates_length_of :name, :in => 6..24
validates_format_of :name, :with => /^[a-z]+$/
validate :name_blacklist
validates_uniqueness_of :email, :case_sensitive => false
validates_format_of :email,
:with => /\A([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
:message => "doesn't look like a proper email address"
#validates_presence_of :password, on: :create
#validates_presence_of :password_confirmation
validates_length_of :password, :in => 6..24
def name_blacklist
unless self.name.blank? then
case self.name
when "user", "photo", "photos",
"application", "sessions",
"identities", "home"
self.errors.add(:name, "prohibited")
end
end
end
end
Identities controllar manage registration form sent to omniauth and calling new.html.erb:
class IdentitiesController < ApplicationController
def new
#identity = env['omniauth.identity']
end
end
Thanks in advance.
I'm not entirely sure what caused the problem, but I came across a similar problem but with email addresses with a Devise based user.
I was wanting to re-use the same email on a different user. I changed the original user to a different email, but when I then tried to update the second user with the "now unique" email, it failed the unique validation.
A query for users with that email returned nothing.
It seemed to be cache-related to the uniqueness constraint, as restarting the server, after deleting the email address, fixed the problem.

Resources