Devise Recoverable says Email can't be blank on Rails 4/5 - ruby-on-rails

Given I am a registered user
And I am not logged in
When I visit "http://localhost:3000/member/password/edit?reset_password_token=BVE492WU1YqMp6nmxCX4"
And I fill in "asdfasdf" in "user[:password]
And I fill in "asdfasdf" in "user[:password_confirmation]
And I submit form
Then I see "Email can't be blank" -> which should be skipped
routes.rb
devise_for :users,
path: 'member',
controllers: {registrations: 'member/registrations',
sessions: 'member/sessions',
passwords: 'member/passwords',
confirmations: 'member/confirmations',
unlocks: 'member/unlocks',
omniauth_callbacks: 'member/omniauth_callbacks'}
devise_scope :user do
match 'member/finish_signup/:id', to: 'member/registrations#finish_signup', via: [:get, :post], :as => :finish_signup
match 'member/show_token', to: 'member/registrations#show_token', via: [:get, :post]
# also tried without the following lines
patch 'member/password' => 'member/passwords#update'
put 'member/password' => 'member/passwords#update'
end
application_controller.rb
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_in, keys: [:email, :password])
devise_parameter_sanitizer.permit(:account_update, keys: [:email, :password, :password_confirmation])
# NONE of the both below change anything
devise_parameter_sanitizer.permit(:sign_up, keys: [:email, :password, :password_confirmation])
# this one does not work anymore
# devise_parameter_sanitizer.for(:sign_up) do |u|
# u.permit(:email,:password,:password_confirmation)
# end
end
passwords/edit.html.erb
<%= form_for(resource, as: resource_name, url: password_path(resource_name), method: :put) do |f| %>
<%= devise_error_messages! %>
<%= f.hidden_field :reset_password_token %>
<% if #minimum_password_length %>
<em>(<%= #minimum_password_length %> characters minimum)</em><br/>
<% end %>
<%= f.password_field :password, autofocus: true, autocomplete: "off" %>
<%= f.password_field :password_confirmation, autocomplete: "off" %>
<%= f.submit "Change my password" %>
<% end %>
also tried this:
<%= form_for(resource, as: resource_name, url: member_password_path(resource_name), html: {method: :put}) do |f| %>
The rendered HTML is which looks good (post method):
<form class="new_user" id="new_user" action="/member/password.user" accept-charset="UTF-8" method="post">
<input name="utf8" type="hidden" value="✓"><input type="hidden" name="_method" value="patch">
<input type="hidden" name="authenticity_token" value="Egh7QFhtHwcBVCuUgTDFnOF2C/g2Ql/sKeiuwjchjmpDh4JqyBPuLTaN9VT9iFFiP7JDxbp0+BeeA2QUSJWN3g==">
<input type="hidden" value="BVE492WU1YqMp6nmxCX4" name="user[reset_password_token]" id="user_reset_password_token">
<em>(8 characters minimum)</em><br>
<input autofocus="autofocus" autocomplete="off" type="password" name="user[password]" id="user_password">
<input autocomplete="off" type="password" name="user[password_confirmation]" id="user_password_confirmation">
<input type="submit" name="commit" value="Change my password" data-disable-with="Change my password">
</form>
member/passwords_controller.rb
class Member::PasswordsController < Devise::PasswordsController
end
rake routes:
new_user_session GET /member/sign_in(.:format) member/sessions#new
user_session POST /member/sign_in(.:format) member/sessions#create
destroy_user_session GET /member/sign_out(.:format) member/sessions#destroy
user_omniauth_authorize GET|POST /member/auth/:provider(.:format) member/omniauth_callbacks#passthru {:provider=>/facebook/}
user_omniauth_callback GET|POST /member/auth/:action/callback(.:format) member/omniauth_callbacks#(?-mix:facebook)
user_password POST /member/password(.:format) member/passwords#create
new_user_password GET /member/password/new(.:format) member/passwords#new
edit_user_password GET /member/password/edit(.:format) member/passwords#edit
PATCH /member/password(.:format) member/passwords#update
PUT /member/password(.:format) member/passwords#update
cancel_user_registration GET /member/cancel(.:format) member/registrations#cancel
user_registration POST /member(.:format) member/registrations#create
new_user_registration GET /member/sign_up(.:format) member/registrations#new
edit_user_registration GET /member/edit(.:format) member/registrations#edit
PATCH /member(.:format) member/registrations#update
PUT /member(.:format) member/registrations#update
DELETE /member(.:format) member/registrations#destroy
user_confirmation POST /member/confirmation(.:format) member/confirmations#create
new_user_confirmation GET /member/confirmation/new(.:format) member/confirmations#new
GET /member/confirmation(.:format) member/confirmations#show
user_unlock POST /member/unlock(.:format) member/unlocks#create
new_user_unlock GET /member/unlock/new(.:format) member/unlocks#new
GET /member/unlock(.:format) member/unlocks#show
finish_signup GET|POST /member/finish_signup/:id(.:format) member/registrations#finish_signup
member_show_token GET|POST /member/show_token(.:format) member/registrations#show_token
member_password PATCH /member/password(.:format) member/passwords#update
PUT /member/password(.:format) member/passwords#update
And this is the log when I submit the filled out "/passwords/edit.html.erb"
(http://localhost:3000/member/password/edit?reset_password_token=BVE492WU1YqMp6nmxCX4)
Started GET "/member/password/edit?reset_password_token=[FILTERED]" for 127.0.0.1 at 2016-03-04 12:40:41 +0100
Processing by Member::PasswordsController#edit as HTML
Parameters: {"reset_password_token"=>"[FILTERED]"}
DEPRECATION WARNING: [Devise] Changing the sanitized parameters through "Devise::ParameterSanitizer#for(sign_up) is deprecated and it will be removed from Devise 4.1.
Please use the `permit` method:
devise_parameter_sanitizer.permit(:sign_up) do |user|
# Your block here.
end
(called from deprecate_for_with_block at /Users/jan/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/devise-4.0.0.rc1/lib/devise/parameter_sanitizer.rb:177)
Rendered devise/shared/_links.html.erb (1.6ms)
Rendered devise/passwords/edit.html.erb within layouts/application (3.5ms)
Completed 200 OK in 14ms (Views: 11.5ms)
Incoming Headers:
Origin: http://localhost:3000
Access-Control-Request-Method:
Access-Control-Request-Headers:
Started POST "/member/password.user" for 127.0.0.1 at 2016-03-04 12:41:19 +0100
Processing by Member::PasswordsController#create as
Parameters: {"utf8"=>"✓", "authenticity_token"=>"gmyAZDVZR4Z/OO3oa934MzNUwCFnzDSd7QLo6ZCoAnjT43lOpSe2rEjhMygXZWzN7ZCIHOv6k2Za6SI/7xwBzA==", "user"=>{"reset_password_token"=>"[FILTERED]", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Change my password"}
Completed 406 Not Acceptable in 2ms
ActionController::UnknownFormat (ActionController::UnknownFormat):
responders (2.1.1) lib/action_controller/respond_with.rb:207:in `respond_with'
devise (4.0.0.rc1) app/controllers/devise/passwords_controller.rb:19:in `create'
/Users/jan/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/bundler/gems/rails-c901fad42cb4/actionpack/lib/action_controller/metal/basic_implicit_render.rb:4:in `send_action'
/Users/jan/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/bundler/gems/rails-c901fad42cb4/actionpack/lib/abstract_controller/base.rb:183:in `process_action'
/Users/jan/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/bundler/gems/rails-c901fad42cb4/actionpack/lib/action_controller/metal/rendering.rb:30:in `process_action'
/Users/jan/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/bundler/gems/rails-c901fad42cb4/actionpack/lib/abstract_controller/callbacks.rb:20:in `block in process_action'
/Users/jan/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/bundler/gems/rails-c901fad42cb4/activesupport/lib/active_support/callbacks.rb:126:in `call'
/Users/jan/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/bundler/gems/rails-c901fad42cb4/activesupport/lib/active_support/callbacks.rb:126:in `call'
/Users/jan/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/bundler/gems/rails-c901fad42cb4/activesupport/lib/active_support/callbacks.rb:506:in `blo
I think the routing from password_path(resource_name) is incorrect. It brings me to member/passwords#create instead of member/passwords#update which seems to be right.
Please, how can I fix this?
.gemfile
gem 'rails', github: "rails/rails"
gem 'active_model_serializers', github: "rails-api/active_model_serializers", branch: 'master'
gem 'mongoid', git: 'https://github.com/estolfo/mongoid.git', branch: 'MONGOID-4218-rails-5'
# api token authentication for devise
gem 'devise', "4.0.0.rc1"
# we can switch back when Rails 5, and Devise 4 is supported
gem 'simple_token_authentication', github: "consti/simple_token_authentication"
gem 'bootstrap_form'
gem 'omniauth'
gem 'omniauth-facebook'

Changing the as: name and the of the route and the method to post did the trick. It seems that they got not overridden in my devise_scope.
'member/password/update' => 'member/passwords#update', as: :member_password_custom_update

Related

Editing user details creates new user. Devise, Rails 4

I have weird problem, previous created form instead of updating user details such as e-mail or name creates new user with given details.
My form:
this code example I took from views/devise/registrations/edit
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { "data-parsley-validate" => true, :id=>"user-edit"},remote: true, format: :json) do |f| %>
<div class="form-group">
<%= f.text_field :name,:class=>"user-input form-control", :id=>"user-name" ,:placeholder=> "Lietotājvārds*",:"data-parsley-group"=>"f1" %>
</div>
<div class="form-group">
<%= f.email_field :email ,:class=>"user-input form-control", :id=>"password",:placeholder=> "E-pasts *",:"data-parsley-group"=>"f2" %>
</div>
<div class="form-group">
<%= f.password_field :current_password, :autocomplete => "off" ,:class=>"user-input form-control", :id=>"password",:placeholder=> "Vecā parole* ",:"data-parsley-group"=>"f3" %>
</div>
<div class="form-group">
<%= f.password_field :password , :class=>"user-input form-control", :id=>"password",:placeholder=> "Jaunā parole* vismaz 8 simboli ", :"data-parsley-group"=>"f3" %>
</div>
<div class="form-group">
<%= f.password_field :password_confirmation , :class=>"user-input form-control", :id=>"password",:placeholder=> "Atkārtot paroli * vismaz 8 simboli ", :"data-parsley-group"=>"f3" %>
</div>
<button type="submit" class="blue-button btn btn-default">Apstiprināt</button>
<%end%>
Routes file:
devise_for :users, :controllers => {:registrations=> "registrations"}
Registration controller:
class RegistrationsController < Devise::RegistrationsController
clear_respond_to
respond_to :json
def sign_up_params
params.require(:user).permit( :email, :password, :password_confirmation,:name, :not_a_robot,:current_password,:bypass_humanizer)
end
def account_update_params
params.require(:user).permit(:name, :email, :password, :password_confirmation, :current_password, :not_a_robot, :bypass_humanizer)
end
private :sign_up_params
private :account_update_params
protected
def update_resource(resource, params)
resource.update_without_password(params)
end
end
In applicaion helper:
module ApplicationHelper
def resource_name
:user
end
def resource
#resource ||= User.new
end
def devise_mapping
#devise_mapping ||= Devise.mappings[:user]
end
end
Log file:
Started POST "/ru/users" for 85.255.65.15 at 2015-09-28 19:32:25 +0300
Processing by RegistrationsController#create as JS
Parameters: {"utf8"=>"✓", "user"=>{"name"=>"ooppapa", "email"=>"test11#!!!", "current_password"=>"[FILTERED]", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "bypass_humanizer"=>"true", "not_a_robot"=>"1"}, "locale"=>"ru"}
[1m[36mBanlist Load (2.0ms)[0m [1mSELECT `banlists`.* FROM `banlists` WHERE (ip_adress = '85.255.65.15')[0m
[1m[35mCountry Load (1.5ms)[0m SELECT `countries`.* FROM `countries` WHERE `countries`.`id` = 1 LIMIT 1
[1m[36mRegion Load (1.3ms)[0m [1mSELECT `regions`.* FROM `regions` WHERE `regions`.`country_id` = 1[0m
[1m[35m (0.4ms)[0m BEGIN
[1m[36mUser Exists (44.1ms)[0m [1mSELECT 1 AS one FROM `users` WHERE `users`.`email` = BINARY 'test11#!!!' LIMIT 1[0m
[1m[35mUser Load (24.3ms)[0m SELECT `users`.* FROM `users` WHERE `users`.`confirmation_token` = '5c5e282bd4c139c7764506b785d54119ceee5499426b555c3650cfc7190ee947' ORDER BY `users`.`id` ASC LIMIT 1
[1m[36mSQL (2.1ms)[0m [1mINSERT INTO `users` (`confirmation_sent_at`, `confirmation_token`, `created_at`, `email`, `encrypted_password`, `name`, `updated_at`) VALUES ('2015-09-28 19:32:29', '5c5e282bd4c139c7764506b785d54119ceee5499426b555c3650cfc7190ee947', '2015-09-28 19:32:28', 'test11#individualki.eu', '$2a$10$mEHajmY0H1NueGrrap7NNu0LuViDEJ.imAS4jhdj1KIyPRIyej/NC', 'ooppapa', '2015-09-28 19:32:28')[0m
Rendered devise/mailer/confirmation_instructions.html.erb (29.2ms)
Devise::Mailer#confirmation_instructions: processed outbound mail in 1726.8ms
Sent mail to test11#!!!.eu (776.1ms)
Date: Mon, 28 Sep 2015 19:32:31 +0300
From: support#!!!!.eu
Reply-To: support#!!!!.eu
To: test11#!!!!.eu
Message-ID: <56096b9f98eb5_25e4640a718550c6#!!!!!>
Subject: Confirmation instructions
Mime-Version: 1.0
Content-Type: text/html;
charset=UTF-8
Content-Transfer-Encoding: 7bit
<p>Welcome !!!</p>
<p>You can confirm your account email through the link below:</p>
My routes:
rake routes
new_user_session GET (/:locale)/users/sign_in(.:format) devise/sessions#new {:locale=>/lv|ee|ru/}
user_session POST (/:locale)/users/sign_in(.:format) devise/sessions#create {:locale=>/lv|ee|ru/}
destroy_user_session DELETE (/:locale)/users/sign_out(.:format) devise/sessions#destroy {:locale=>/lv|ee|ru/}
user_password POST (/:locale)/users/password(.:format) devise/passwords#create {:locale=>/lv|ee|ru/}
new_user_password GET (/:locale)/users/password/new(.:format) devise/passwords#new {:locale=>/lv|ee|ru/}
edit_user_password GET (/:locale)/users/password/edit(.:format) devise/passwords#edit {:locale=>/lv|ee|ru/}
PATCH (/:locale)/users/password(.:format) devise/passwords#update {:locale=>/lv|ee|ru/}
PUT (/:locale)/users/password(.:format) devise/passwords#update {:locale=>/lv|ee|ru/}
cancel_user_registration GET (/:locale)/users/cancel(.:format) registrations#cancel {:locale=>/lv|ee|ru/}
user_registration POST (/:locale)/users(.:format) registrations#create {:locale=>/lv|ee|ru/}
new_user_registration GET (/:locale)/users/sign_up(.:format) registrations#new {:locale=>/lv|ee|ru/}
edit_user_registration GET (/:locale)/users/edit(.:format) registrations#edit {:locale=>/lv|ee|ru/}
PATCH (/:locale)/users(.:format) registrations#update {:locale=>/lv|ee|ru/}
PUT (/:locale)/users(.:format) registrations#update {:locale=>/lv|ee|ru/}
DELETE (/:locale)/users(.:format) registrations#destroy {:locale=>/lv|ee|ru/}
user_confirmation POST (/:locale)/users/confirmation(.:format) devise/confirmations#create {:locale=>/lv|ee|ru/}
new_user_confirmation GET (/:locale)/users/confirmation/new(.:format) devise/confirmations#new {:locale=>/lv|ee|ru/}
GET (/:locale)/users/confirmation(.:format) devise/confirmations#show {:locale=>/lv|ee|ru/}
update_password_user PATCH (/:locale)/user/update_password(.:format) users#update_password {:locale=>/lv|ee|ru/}
edit_user GET (/:locale)/user/edit(.:format) users#edit {:locale=>/lv|ee|ru/}
sms_receive GET (/:locale)/sms/receive(.:format) sms#receive {:locale=>/lv|ee|ru/}
root GET /(:locale)(.:format) girls#index {:locale=>/lv|ee|ru/}
I am confused. Is it registration_path(resource_name) that creates this error?
Any advise could be helpful.!
thanks in advance.
The issue is in the form as it is pointing to the registration_path(resource_name) path.
The example you are using is taken from How To: Allow users to edit their account without providing a password and it says:
and provide an edit and update actions, as you would do for any other
resource in your application.
Which means you need to create a route to the edit method and use it as you wish.
The example above is for updating the user without the password, but what you are doing is updating the password.
For the solutions, read How To: Allow users to edit their password
An example solution - #3:
UsersController
class UsersController < ApplicationController
before_filter :authenticate_user!
def edit
#user = current_user
end
def update_password
#user = User.find(current_user.id)
if #user.update(user_params)
# Sign in the user by passing validation in case their password changed
sign_in #user, :bypass => true
redirect_to root_path
else
render "edit"
end
end
private
def user_params
# NOTE: Using `strong_parameters` gem
params.require(:user).permit(:password, :password_confirmation)
end
end
If you are using several scopes, specify the one you are signing in:
sign_in :user, #user, bypass: true
The route should be the following:
resource :user, only: [:edit] do
collection do
patch 'update_password'
end
end
View
<%= form_for(#user, :url => { :action => "update_password" } ) do |f| %>
<div class="field">
<%= f.label :password, "Password" %><br />
<%= f.password_field :password, :autocomplete => "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %>
</div>
<div class="action_container">
<%= f.submit %>
</div>
<% end %>
To use "confirm_password" field to force user to enter old password
before updating with the new one: Change #user.update(user_params) to
#user.update_with_password(user_params) in the controller along with
adding :current_password to the permitted parameters, then and add the
following to the view code:
<div class="field">
<%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password %>
</div>
Remember, Devise models are like any model in your application. If you
want to provide custom behavior, just implement new actions and new
controllers. Don't try to bend Devise.
I saw your question and maybe the problem is on form call.
Try insert html: { method: :put }. With simple_form I use this way:
= simple_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f|
How you omitted the method of send the form, it's sending as post and creating a new record, I presume.

Routing Error when trying to update Devise user details, Rails 4

I am trying to fix issues with changing Devise user details in Rails 4 project. Based on this question
Layout:
<div class="modal fade" id="user-profile" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog log-modal">
<div class="modal-content">
<%= render partial: "shared/profile" %>
</div>
</div>
</div>
_profile partial.
<%= form_for(#user, :url => { :action => "update_password",:controller =>"users" } ,remote: true, format: :json) do |f| %>
<div class="form-group">
<%= f.text_field :name,:class=>"user-input form-control", :id=>"user-name" ,:placeholder=> "Lietotājvārds*",:"data-parsley-group"=>"f1" %>
</div>
<div class="form-group">
<%= f.email_field :email ,:class=>"user-input form-control", :id=>"password",:placeholder=> "E-pasts *",:"data-parsley-group"=>"f2" %>
</div>
<div class="form-group">
<%= f.password_field :current_password, :autocomplete => "off" ,:class=>"user-input form-control", :id=>"password",:placeholder=> "Vecā parole* ",:"data-parsley-group"=>"f3" %>
</div>
<div class="form-group">
<%= f.password_field :password , :class=>"user-input form-control", :id=>"password",:placeholder=> "Jaunā parole* vismaz 8 simboli ", :"data-parsley-group"=>"f3" %>
</div>
<div class="form-group">
<%= f.password_field :password_confirmation , :class=>"user-input form-control", :id=>"password",:placeholder=> "Atkārtot paroli * vismaz 8 simboli ", :"data-parsley-group"=>"f3" %>
</div>
<button type="submit" class="blue-button btn btn-default">Apstiprināt</button>
<%end%>
My routes file:
Rails.application.routes.draw do
get 'banned/index'
get 'reusable/login'
get 'reusable/registration'
get 'reusable/password_recovery'
resources :menus
resources :blocked do
collection do
get 'checktoken'
get 'checkemail'
end
member do
post 'toggle'
post 'rev'
end
end
ActiveAdmin.routes(self)
scope "(:locale)", :locale => /lv|ee|ru/ do
devise_for :users, :controllers => {:registrations=> "registrations"}
resource :user, only: [:edit] do
collection do
patch 'update_password'
end
end
resources "successful-registration", :controller => :successful_registration, :as => :successful_registration
resources :replies do
member do
put "like", to: "replies#upvote"
put "dislike", to: "replies#downvote"
end
end
resources :reviews do
member do
put "like", to: "reviews#upvote"
put "dislike", to: "reviews#downvote"
put "downwote", to: "reviews#complaints"
end
end
resources :reports
resources :offers
resources :messages
resources :feedbacks
resources :girls do
collection do
get 'checktoken'
get 'checkemail'
end
member do
put "like", to: "girls#upvote"
put "dislike", to: "girls#downvote"
post 'toggle'
end
end
get 'sms/receive/', to: 'sms#receive'
root 'girls#index'
end
end
Log file:
Started POST "/ru/user/update_password" for 212.93.100.35 at 2015-10-03 14:08:12 +0300
ActionController::RoutingError (No route matches [POST] "/ru/user/update_password"):
actionpack (4.1.6) lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
actionpack (4.1.6) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
railties (4.1.6) lib/rails/rack/logger.rb:38:in `call_app'
What I tried:
1) Restarted server
2) Tried to change order of the user routes.
I have no other ideas to try. Any help ?
Thanks in advance.
It seems you have routing for PATCH request (patch 'update_password') but you are sending POST request.
Edit your routing file (post 'update_password') or use PATCH request:
<%= form_for(#user, :url => { :action => "update_password",:controller =>"users",method: "patch" },remote: true, format: :json) do |f| %>
As an addition to the answer, you should also be considering how Devise would provide you with user account change functionality:
# # Password routes for Recoverable, if User model has :recoverable configured
# new_user_password GET /users/password/new(.:format) {controller:"devise/passwords", action:"new"}
# edit_user_password GET /users/password/edit(.:format) {controller:"devise/passwords", action:"edit"}
# user_password PUT /users/password(.:format) {controller:"devise/passwords", action:"update"}
# POST /users/password(.:format) {controller:"devise/passwords", action:"create"}
If you use rake routes, you'll see which Devise routes you have access to, and which you're able to use.
If you're looking to use Devise to handle this (which it appears you are), you can either use the above routes (which will become accessible if you add :recoverable to your User model Devise definitions), or if you call them directly.
If you want to add / edit Devise routes explicitly, you'll be able to do the following:
devise_for :users, controllers: { registrations: "registrations" } do
patch "passwords/update" => "passwords#update", :as => :password_update
end
--
I also see a lot of your routes being specifically defined. Although nothing wrong with this, it's very inefficient and actually prevents your app from being able to harness its true potential.
Here are some examples I would recommend you investigate:
#config/routes.rb
resources :reusable, only: [] do
collection do
get :login
get :registration
get :password_recovery
end
end
Another one is to define multiple resources in one batch...
resources :reports, :offers, :messages, :feedbacks

Get NoMethodError in Devise::RegistrationsController#create

trying to add new users , using the devise gem
ran rake db:migrate and ran the rails server again
but when i type in 3000/posts/sign_up
it gives me the default sign up screen but when try to create a user i get
NoMethodError in Devise::RegistrationsController#create
undefined method `encrypted_password=' for #
my logs show
Started POST "/posts" for 127.0.0.1 at 2014-03-18 20:38:22 +0000
Processing by Devise::RegistrationsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"2uO2ttqAfK1a2C855cZOpDTsS2Duc7ZzVJxAQ5ObL8M=", "post"=>{"email"=>"neil#example.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Sign up"}
Completed 500 Internal Server Error in 79ms
NoMethodError (undefined method `encrypted_password=' for #<Post:0x007fde3e09e538>):
activemodel (4.0.4) lib/active_model/attribute_methods.rb:439:in `method_missing'
activerecord (4.0.4) lib/active_record/attribute_methods.rb:167:in `method_missing'
devise (3.2.2) lib/devise/models/database_authenticatable.rb:42:in `password='
activerecord (4.0.4) lib/active_record/attribute_assignment.rb:42:in `public_send'
activerecord (4.0.4) lib/active_record/attribute_assignment.rb:42:in `_assign_attribute'
activerecord (4.0.4) lib/active_record/attribute_assignment.rb:29:in `block in assign_attributes'
activerecord (4.0.4) lib/active_record/attribute_assignment.rb:23:in `each'
activerecord (4.0.4) lib/active_record/attribute_assignment.rb:23:in `assign_attributes'
new.html.erb
<h2>Sign up</h2>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :email %><br />
<%= f.email_field :email, :autofocus => true %></div>
<div><%= f.label :password %><br />
<%= f.password_field :password %></div>
<div><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %></div>
<div><%= f.submit "Sign up" %></div>
<% end %>
<%= render "devise/shared/links" %>
post.rb
class Post < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
rake routes
Prefix Verb URI Pattern Controller#Action
new_post_session GET /posts/sign_in(.:format) devise/sessions#new
post_session POST /posts/sign_in(.:format) devise/sessions#create
destroy_post_session DELETE /posts/sign_out(.:format) devise/sessions#destroy
post_password POST /posts/password(.:format) devise/passwords#create
new_post_password GET /posts/password/new(.:format) devise/passwords#new
edit_post_password GET /posts/password/edit(.:format) devise/passwords#edit
PATCH /posts/password(.:format) devise/passwords#update
PUT /posts/password(.:format) devise/passwords#update
cancel_post_registration GET /posts/cancel(.:format) devise/registrations#cancel
post_registration POST /posts(.:format) devise/registrations#create
new_post_registration GET /posts/sign_up(.:format) devise/registrations#new
edit_post_registration GET /posts/edit(.:format) devise/registrations#edit
PATCH /posts(.:format) devise/registrations#update
PUT /posts(.:format) devise/registrations#update
DELETE /posts(.:format) devise/registrations#destroy
posts GET /posts(.:format) posts#index
POST /posts(.:format) posts#create
new_post GET /posts/new(.:format) posts#new
edit_post GET /posts/:id/edit(.:format) posts#edit
post GET /posts/:id(.:format) posts#show
PATCH /posts/:id(.:format) posts#update
PUT /posts/:id(.:format) posts#update
DELETE /posts/:id(.:format) posts#destroy
about GET /about(.:format) pages#about
root GET / pages#welcome
rails g
Neils-MacBook-Pro:prospects neilpatel$ rails g devise:views
invoke Devise::Generators::SharedViewsGenerator
create app/views/devise/shared
create app/views/devise/shared/_links.erb
invoke form_for
create app/views/devise/confirmations
create app/views/devise/confirmations/new.html.erb
create app/views/devise/passwords
create app/views/devise/passwords/edit.html.erb
create app/views/devise/passwords/new.html.erb
create app/views/devise/registrations
create app/views/devise/registrations/edit.html.erb
create app/views/devise/registrations/new.html.erb
create app/views/devise/sessions
create app/views/devise/sessions/new.html.erb
create app/views/devise/unlocks
create app/views/devise/unlocks/new.html.erb
invoke erb
create app/views/devise/mailer
create app/views/devise/mailer/confirmation_instructions.html.erb
create app/views/devise/mailer/reset_password_instructions.html.erb
create app/views/devise/mailer/unlock_instructions.html.erb
Neils-MacBook-Pro:prospects neilpatel$ rails generate devise Post
invoke active_record
create db/migrate/20140318202353_add_devise_to_posts
insert app/models/post.rb
route devise_for :posts
Neils-MacBook-Pro:prospects neilpatel$ rake db:migrate
The main problem is here
NoMethodError (undefined method `encrypted_password=' for #<Post:0x007fde3e09e538>):
Check out you migration file. Is encrypted_password present or not? Do you have this t.string :encrypted_password, :null => false, :default => "" line of code in your migration file. And in your model file (i.e post.rb) you haven't define password attribute too.

Rails form not using explicit action

I'm a noob that's been struggling with this problem for longer than I care to admit. I used to have a routing issue with my STI model, but now I think that's solved (thanks to SO).
My problem is once I update the form at : /kids/1/edit, instead of having the record saved, it seems to get the record again. I know I'm missing something basic, yet after working the issue a long time the answer eludes me. You can see I'm explicitly calling the kidupdate action with the form submission.
thanks in advance.
kidedit.html.erb
<% provide(:title, "Edit user") %>
<h1>Update your profile</h1>
<div class="row">
<div class="span5 offset3">
<%= form_for(#kid, url: kidedit_path) do |f| %>
<#%= render 'shared/error_messages', object: f.object %>
<%= f.label :fname, "First Name" %>
<%= f.text_field :fname %>
<%= f.label :lname, "Last Name" %>
<%= f.text_field :lname %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.label :type, "Are you a Kid or Parent" %>
<%= f.select :type, [['Kid','Kid'],['Parent','Parent']] %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.label :password_confirmation, "Confirmation" %>
<%= f.password_field :password_confirmation %>
<%= f.submit "Save changes", class: "btn btn-large btn-primary", :controller => 'users', :action => 'kidupdate' %>
<% end %>
</div>
</div>
users_controller.rb
def kidupdate
#kid = Kid.find(params[:id])
if #kid.update_attributes(params[:kid])
flash[:success] = "Profile updated"
sign_in #kid
redirect_to kidshow_path
else
render kidedit_path(#kid)
end
end
routes.rb
Kidtunes::Application.routes.draw do
root to: 'static_pages#home'
match '/help', to: 'static_pages#help'
match '/contact', to: 'static_pages#contact'
match '/signup', to: 'users#new'
match '/signin', to: 'sessions#new'
match '/signout', to: 'sessions#destroy', via: :delete
match 'kids/:id' => 'users#kidupdate', via: :put, :as => :kidupdate
match 'kids/:id' => 'users#kidshow', via: :get, :as => :kidshow
match 'kids/:id/edit' => 'users#kidedit', :as => :kidedit
resources :users
resources :sessions, only: [:new, :create, :destroy]
Here's what's in the server log:
Started PUT "/kids/1/edit" for 127.0.0.1 at 2012-11-05 07:52:28 -0500
Processing by UsersController#kidedit as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"T8RqFt9lxdbZU+1cOh2E5yu2CFbVRDGmRcj2XdDN1ZU=", "user"=>{"fname"=>"Dante", "lname"=>"Refford", "email"=>"drefford#example.com", "type"=>"Kid", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Save changes", "id"=>"1"}
Kid Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."type" IN ('Kid') AND "users"."id" = ? LIMIT 1 [["id", "1"]]
Rendered users/kidedit.html.erb within layouts/application (4.1ms)
Rendered layouts/_shim.html.erb (0.0ms)
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = '1RZr3qfB6QSh42_jQ9qNWQ' LIMIT 1
Rendered layouts/_header.html.erb (2.5ms)
Rendered layouts/_footer.html.erb (0.3ms)
Completed 200 OK in 67ms (Views: 46.3ms | ActiveRecord: 1.0ms)
Routes
$rake routes
root / static_pages#home
help /help(.:format) static_pages#help
contact /contact(.:format) static_pages#contact
signup /signup(.:format) users#new
signin /signin(.:format) sessions#new
signout DELETE /signout(.:format) sessions#destroy
kidupdate PUT /kids/:id(.:format) users#kidupdate
kidshow GET /kids/:id(.:format) users#kidshow
kidedit /kids/:id/edit(.:format) users#kidedit
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
sessions POST /sessions(.:format) sessions#create
new_session GET /sessions/new(.:format) sessions#new
session DELETE /sessions/:id(.:format) sessions#destroy
As the first comment said, the form should be using the update_path method:
<%= form_for(#kid, url: kidupdate_path) do |f| %>

Trying to learn rails and keep hitting noMethodError

I've gone through the getting started with rails tutorial and now i'm trying to setup another project using the devise gem for authentication. Basically all i want is to have a home page, a page where the user can fill out a form to essentially signup, and then a secure page that does the authentication.
right now i'm having problems when i navigate to the signup page. Here's the error i'm receiving:
NoMethodError in Signup#index
Showing /Users/tomcaflisch/Sites/project2/app/views/signup/_form.html.erb where line #1 raised:
undefined method `users_path' for #<#<Class:0x007fa734b3e510>:0x007fa734b3a910>
Extracted source (around line #1):
1: <%= form_for(#user) do |f| %>
2: <% if #user.errors.any? %>
3: <div id="errorExplanation">
4: <h2><%= pluralize(#user.errors.count, "error") %> prohibited this post from being saved: </h2>
signup_controller.rb:
class SignupController < ApplicationController
def index
#user = User.new
end
def new
#user = User.new
respond_to do |format|
format.html
end
end
end
user.rb model:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :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, :username
end
../views/signup_form.html.erb:
<%= form_for(#user) do |f| %>
<% if #user.errors.any? %>
<div id="errorExplanation">
<h2><%= pluralize(#user.errors.count, "error") %> prohibited this post from being saved: </h2>
<ul>
<% #user.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :email %><br />
<%= f.text_field :email %>
</div>
<div class="field">
<%= f.label :username %><br />
<%= f.text_field :username %>
</div>
<div class="field">
<%= f.label :password %><br />
<%= f.text_field :password %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
routes.rb:
get "signup/index"
devise_for :users
get "index/index"
root :to => 'index#index'
$ bundle exec rake routes | grep user:
new_user_session GET /users/sign_in(.:format) {:action=>"new", :controller=>"devise/sessions"}
user_session POST /users/sign_in(.:format) {:action=>"create", :controller=>"devise/sessions"}
destroy_user_session DELETE /users/sign_out(.:format) {:action=>"destroy", :controller=>"devise/sessions"}
user_password POST /users/password(.:format) {:action=>"create", :controller=>"devise/passwords"}
new_user_password GET /users/password/new(.:format) {:action=>"new", :controller=>"devise/passwords"}
edit_user_password GET /users/password/edit(.:format) {:action=>"edit", :controller=>"devise/passwords"}
PUT /users/password(.:format) {:action=>"update", :controller=>"devise/passwords"}
cancel_user_registration GET /users/cancel(.:format) {:action=>"cancel", :controller=>"devise/registrations"}
user_registration POST /users(.:format) {:action=>"create", :controller=>"devise/registrations"}
new_user_registration GET /users/sign_up(.:format) {:action=>"new", :controller=>"devise/registrations"}
edit_user_registration GET /users/edit(.:format) {:action=>"edit", :controller=>"devise/registrations"}
PUT /users(.:format) {:action=>"update", :controller=>"devise/registrations"}
DELETE /users(.:format) {:action=>"destroy", :controller=>"devise/registrations"}
It looks like you're mixing two things: devise provides it's own signup / registration pages, and you've also created your own.
Sometimes that's appropriate, but many times the default devise pages are good enough -- or at least good enough to start with.
I'd recommend you begin by trying to implement devise with it's own pages -- leaving your signin and signup pages alone for now. You don't see the devise pages because they are hidden inside the gem.
If you want to customize them, you can get the devise pages installed in your project (in a haml format) by following the steps here:
https://github.com/plataformatec/devise/wiki/How-To:-Create-Haml-and-Slim-Views
Because you are creating you're own signup controller, I believe devise routes are not routing where you like
post your routes file and lets see if we can get your routes straightened out.
It is looking for Signup#index .. It should be looking for SignupController#index
in your routes.rb you want to have
root :to => 'signup#index'
Also, undefined method users_path is missing its route to get the users or most likely missing resources :users from your routes.rb
For a new user you want something like form_for(User.new) which will hit UsersController#new
__
Or do it this way
1)
For views/users/new.html.erb you want
<%= form_for(#user) do |f| %>
<%= render 'fields', :f => f %>
....
with a route to it something like get '/signup', :to => 'users#new' and link_to 'Signup', signup_path
2)
For UsersController add
def new
#user = User.new
..
end

Resources