Devise new user password and edit user password Redirect to many times, can't go through Forgot password - devise

The links are straightforward
<%= link_to 'new_user_password', new_user_password_path %>
<%= link_to 'edit_user_password', edit_user_password_path %>
the routes are:
devise_for :users
and I've tried with:
devise_for :users, :controllers => {:passwords => 'passwords'}
Inheriting the Devise::Passwords controller in the passwords controller. But I can't seem to get past the redirects.
I have:
before_action :sanitize_devise_params, if: :devise_controller?
before_action :configure_permitted_parameters, if: :devise_controller?
before_action :set_auth
def sanitize_devise_params
devise_parameter_sanitizer.permit(:sign_up, keys: [:username, :privacy, :organization])
devise_parameter_sanitizer.permit(:account_update, keys: [:username, :privacy, :organization])
end
def configure_permitted_parameters
update_attrs = [:password, :password_confirmation, :current_password]
devise_parameter_sanitizer.permit :account_update, keys: update_attrs
end
def set_auth
#auth = session[:omniauth] if session[:omniauth]
end
I can't tell where else there might be a fault that would cause this to break like this.

I just had to clear the cookies

Related

Rails 3.0 devise account validation from admin to user - undefined method `edit_user_path'

I'm trying to make an admin account to validate the registration of a user, for that I have 2 devise models: admin and user.
I've followed these steps:
https://github.com/plataformatec/devise/wiki/How-To%3a-Require-admin-to-activate-account-before-sign_in
But from the view I get this error:
Undefined method `edit_user_path'
This is my app/models/user.rb
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
attr_accessible :email, :password, :password_confirmation, :remember_me
def active_for_authentication?
super && approved?
end
def inactive_message
if !approved?
:not_approved
else
super # Use whatever other message
end
end
def self.send_reset_password_instructions(attributes={})
recoverable = find_or_initialize_with_errors(reset_password_keys, attributes, :not_found)
if !recoverable.approved?
recoverable.errors[:base] << I18n.t("devise.failure.not_approved")
elsif recoverable.persisted?
recoverable.send_reset_password_instructions
end
recoverable
end
end
App/controllers/unapproved_users_controller.rb
class UnapprovedUsersController < ApplicationController
def index
if params[:approved] == "false"
#users = User.find_all_by_approved(false)
else
#users = User.all
end
end
end
App/views/unapproved_users.html.haml
%h1 Users
= link_to "All Users", :action => "index"
|
= link_to "Users awaiting approval", :action => "index", :approved => "false"
%table
- #users.each do |user|
%tr
%td= user.email
%td= user.approved
%td= link_to "Edit", edit_user_path(user)
This path makes the problem:
= link_to "Edit", edit_user_path(user)
Option #1 - Check rake routes for the correct helper
Option #2 - You need to setup an administrator interface to edit users as I'm pretty sure devise only provides the interface for current_user not for people wanting to edit another user.
Option #3 - Use something like RailsAdmin

Nested resources create Couldn't find Topic without an ID

I wanna make an application which User can create a topic and others can make posts after that. I nested my resources in my routes.rb:
MyPedia2::Application.routes.draw do
resources :users
resources :sessions, only: [:new, :create, :destroy]
resources :topics, only: [:show, :create, :destroy]
resources :posts
resources :topics do
resources :posts, only: [:create, :show, :new]
end
In my topic show page , I want to show topic.title and sended Posts and post.form.html.erb.
Everything works accept when i create a post , I get mistake
ActiveRecord::RecordNotFound in PostsController#create
Couldn't find Topic without an ID..
This is my posts_controller.rb:
class PostsController < ApplicationController
before_filter :signed_in_user, only: [:create, :destroy]
before_filter :correct_user, only: :destroy
def new
#topic= Topic.find_by_id(params[:id])
#post = #topic.posts.build(params[:post])
end
def show
#topic = Topic.find(params[:id])
#posts = #topic.posts.paginate(page: params[:page])
end
def create
#topic = Topic.find(params[:id])
#post = #topic.posts.build(params[:post])
#post.topic = #topic
if #post.save
flash[:success] = "Konu oluşturuldu!"
redirect_to :back
else
render 'static_pages/home'
end
end
def destroy
#post.destroy
redirect_to root_path
end
private
def correct_user
#post = current_user.posts.find_by_id(params[:id])
redirect_to root_path if #post.nil?
end
end
and _post_form.html.erb:
<%= form_for #new_post do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.text_area :content, placeholder: "yorumunuzu girin..." %>
</div>
<%= f.submit "Gönder", class: "btn btn-large btn-primary" %>
<% end %>
There are a few things that should solve things for you.
First and foremost, your create action in the posts controller is a bit wrong - it should look something like this:
def create
#topic = Topic.find(params[:topic_id])
#post = #topic.posts.build(params[:post])
# This is unnecessary as you're already adding
# the post to the topic with the build statement.
# #post.topic = #topic
if #post.save
flash[:success] = "Konu oluşturuldu!"
redirect_to :back
else
render 'static_pages/home'
end
end
This controller action assumes that you're going to use a put request to a post resource that is nested in topics, so you'll have to clean up your routes.
You have routes to posts#create both nested and unnested.
If posts are ALWAYS supposed to be nested within a topic, which your controller logic is stating, then you should add this to the unnested posts resource:
resources :posts, except: [:new, :create]
and then change that form_for tag to this:
<%= form_for [#topic, #post] do |f| %>
This tells the form builder that you're using a nested resource and will use the correct url for the http request.
Also - it looks like you're using loading all of your topics using Topic.find(params[:id]). This isn't going to work - you're in the posts controller, this is a post id. You should be loading posts with the id param like this: Post.find(params[:id]) and then the topic like this: topic = post.topic

Devise: change password

I've been stuck on this for over 24hrs trying to follow other solutions posted here, but I can't get this to work. I'm new to Rails and need help!
I want to get my /users/edit page working so that I can simply change a users password. Originally, I wanted to do it without current_password but I don't mind leaving it in there as long as I can get the password changing and updating.
Here's what I did:
I followed the example in the Devise Wiki and inserted it into my Users controller which I specified to inherit from Devise::RegistrationsController
class UsersController < Devise::RegistrationsController
...
end
I changed my routes:
devise_for :users, :controllers => { :registrations => 'users' } do
match '/users' => 'users#index'
end
And here's my model:
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
attr_accessor :password, :password_confirmation, :current_password
attr_accessible :email, :password, :password_confirmation, :current_password, :remember_me, :full_name, :coach, :bio
validates :full_name, presence: true
end
I was assuming the UsersController I created would override the Registrations controller and that I would be able to change/update password. It works to the extent the redirect to root_path happens (which is only meant to happen after updating without current password) but the new password is not saved (I checked the logs and there was no SQL to show it was saved)...
Any ideas?
Try doing something similar to:
Devise Forgot Password for logged in user
This lets you have a separate view for changing the password.
The key is that I couldn't ever get it working in devise, so I wrote my own solution in the users controller and post to that instead of using the methods provided by devise.
add this to your user form where you want to be able to edit the password:
<%= form_for(#user, :url => url_for(:action => :do_reset_password) , :html => { :method => :post }) do |f| %>
<%= f.hidden_field :reset_password_token %>
<div><%= f.label :password, "New password" %><br />
<%= f.password_field :password %></div>
<div><%= f.label :password_confirmation, "Confirm new password" %><br />
<%= f.password_field :password_confirmation %></div>
<div><%= f.submit "Change my password" %></div>
<% end %>
users controller:
def do_reset_password
id = params[:id]
# there may be a better way of doing this, devise should be able to give us these messages
if params[:user][:password] != params[:user][:password_confirmation]
flash[:alert] = "Passwords must match."
redirect_to :back
return
end
if #user.reset_password!(params[:user][:password],params[:user][:password_confirmation])
#user.save
respond_to do |format|
format.html { redirect_to '/home', notice: 'Your password has been changed.' }
end
else
flash[:alert] = "Invalid password, must be at least 6 charactors."
redirect_to :back
end
end
config/routes.rb
resource :users do
post 'do_reset_password'
end

Nested model form not working properly - need to pinpoint POST/GET redirect

I have a nested model form that isn't functioning properly. The POST is to the proper place, but then the GET reroutes me. So I'm wondering if anyone can help explain what I'm doing wrong.
I have two models: User and Profile. Code for them below:
User:
class User < ActiveRecord::Base
attr_accessor :password, :email
has_one :profile, :dependent => :destroy
accepts_nested_attributes_for :profile
...
end
Profile:
class Profile < ActiveRecord::Base
attr_accessible :first_name, :last_name, etc.
belongs_to :user
accepts_nested_attributes_for :user
...
end
New/Create from both models:
class UsersController < ApplicationController
def new
#user = User.new
if logged_in?
redirect_to current_user.profile
end
end
def create
#user = User.new(params[:user])
if #user.save
redirect_to signup_path, :notice => 'User successfully added.'
else
render :action => 'new'
end
end
class ProfilesController < ApplicationController
def new
#profile = Profile.new
end
def create
#profile = Profile.new(params[:profile])
if #profile.save
redirect_to profile_path, :notice => 'User successfully added.'
else
render :action => 'new'
end
end
def index
#profile = current_user.profile
end
My signup (two step process) mixes the models, so as I said I'm using a nested model form in my Users new.html.erb file. Code form_for and f.fields_for below:
<%= form_for(:user, :url => signup_path, :html => {:id => 'homepage'}) do |f| %>
<%= f.fields_for :profile do |f| %>
Now when I enter data into the form, my routes.rb file seems to POST to the proper place (/signup so profile can be filled out further), but GET routes me to /login.
Routes.rb:
match '/login' => "sessions#new", :as => "login"
match '/signup' => 'profiles#new', :as => "signup"
match 'skip/signup', :to => 'info#signupskip'
match 'skip/profiles/new', :to => 'profiles#newskip'
root :to => 'users#new'
resources :users
resources :profiles
In rails server:
Started POST "/signup" for 127.0.0.1 at Sun Aug 28 19:54:11 -0400 2011
Processing by ProfilesController#new as HTML
Started GET "/login" for 127.0.0.1 at Sun Aug 28 19:54:11 -0400 2011
Processing by SessionsController#new as HTML
Rendered sessions/new.html.erb within layouts/application (32.1ms)
I'm wondering if the problem is in my layouts/application file, specifically this code:
<% if logged_in? %>
<%= render 'layouts/header_in' %>
<% else %>
<%= render 'layouts/header_out' %>
<% end %>
Can anyone help explain to me what I'm doing wrong?
UPDATE:
I deleted the if/else argument in `layouts/application' and it was still redirected. So I'm back to wondering what's going on.
I believe your problem has to do with an inherent issue (though arguably not problem) with HTTP protocol. You cannot return a redirect to a POST request. Alternatives include calling the other method from within the first controller action, or rendering the correct page directly from that action, or some mix of both.

CanCan polymorphic resource access problem

i don't quite understand how to restrict access to links in this particular case with CanCan. I always get "Edit" link displayed.
So i believe the problem is in my incorrect definition of cancan methods(load_ and authorize_).
I have CommentsController like that:
class CommentsController < ApplicationController
before_filter :authenticate_user!
load_resource :instance_name => :commentable
authorize_resource :article
def index
#commentable = find_commentable #loading our generic object
end
......
private
def find_commentable
params.each { |name, value|
if name =~ /(.+)_id$/
return $1.classify.constantize.includes(:comments => :karma).find(value)
end }
end
end
and i have in comments/index.html.erb following code that render file from other controller:
<%= render :file => "#{get_commentable_partial_name(#commentable)}/show.html.erb", :collection => #commentable %>
you can think about "#{get_commentable_partial_name(#commentable)}" like just "articles" in this case.
Content of "articles/show.html.erb":
<% if can? :update, #commentable %>
<%= link_to 'Edit', edit_article_path(#commentable) %> |
<% end %>
my ability.rb:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user
if user.role? :admin
can :manage, :all
elsif user.role? :author
can :read, [Article, Comment, Profile]
can :update, Article, :user_id => user.id
end
end
end
i have tried debug this issue like that
user = User.first
article = Article.first
ability = Ability.new(user)
ability.can?(:update, article)
and i always get "=> true" in ability check
Note: user.role == author and article.user_id != user.id
if you need more information please write
thank's for your time && sorry for my english
okay i figure it out, redetermined rules in ability.rb so now order is like guest->author->moderator->admin and problem is solved. I believe root of problem was in cancan logic which assumes that i need to redefine rules or do it in order i've show before