Got error from devise user and wicked rails gem - ruby-on-rails

I got error from browser after sign up with email and password.
class UserStepsController < ApplicationController
steps :personal
def show
#user = current_user
render_wizard
end
def update
#user = current_user
#user.update_attributes(user_params)
render_wizard #user
end
def finish_wizard_path
flash[:notice] = "You have successfully Registered With The Wizard."
user_path(current_user)
end
private
def user_params
params.require(:user).permit(:first_name, :last_name, :degree_level, :role, :email, :password )
end
end
On RegistrationsController < Devise::RegistrationsController
class RegistrationsController < Devise::RegistrationsController
def new
super
end
def create
super
end
protected
def after_sign_up_path_for(resource)
'/user_steps'
end
end
I allready added routes resources :user_steps, devise_for :users, :controllers => { :registrations => "registrations" }
my devise/registrations/new
<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :email, required: true, autofocus: true %>
<%= f.input :password, required: true %>
<%= f.input :password_confirmation, required: true %>
</div>
<div class="form-actions">
<%= f.button :submit, "Sign up" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
Added personal.html.erb first name, last name and degree_level
<%= form_for(#user, :url => wizard_path, :method => :put) do |f|%>
<%= f.text_field :first_name %>
<%= f.text_field :last_name %>
<%= f.text_field :degree_level %>
<%= f.submit 'submit', :class => "btn btn-primary" %>
<%end%>
user model added validates presence.
This error show after sign up with email and password
error message is Please review the problems below:

Sorry i want add include Wicked::Wizard

Related

ActiveRecord::RecordNotFound (Couldn't find User without an ID)

Ive currently created an app that is meant to mimic fiverr, im currently trying to create a registration form for users who are currently active on the site, as freelancers, this is being handled using the Devise gem on ruby. Im having a problem when posting my form however, as it keeps coming back saying it couldnt find the user without an ID.
Here below is my form
```ruby
<%= form_with model: #user do |form|%>
<%= form.text_field :first_name, placeholder: "First Name"%>
<%= form.text_field :last_name, placeholder: "Last Name"%>
<%= form.text_field :bio, placeholder: "Bio"%>
<%= form.number_field :cost, placeholder: "Cost per hour in $'s"%>
<%= form.submit %>
<%end%>```
and then here is my pages_controller
```ruby
class PagesController < ApplicationController
def home
end
def registration_form
end
def edit
#user = User.find(params[:id])
end
def register_freelancer
#user = User.find(params[:id])
#user.update(seller_params)
current_user.freelancer!
redirect_back(fallback_location: root_path)
end
private
def seller_params
params.require(:user).permit(:first_name, :last_name, :bio, :cost)
end
end
```
Here is my routes
```ruby
Rails.application.routes.draw do
root 'pages#home'
devise_for :users
resources :pages
get '/home' => 'pages#home'
get '/registration_form' => 'pages#registration_form'
post 'registration_form' => 'pages#register_freelancer'
end
and here is a screenshot of my table
[table][4]
Im using ruby on rails 7.0, and a postgres database, please can someone advise me what step im missing out on to update these database?
[1]: https://i.stack.imgur.com/z4cnn.png
[2]: https://i.stack.imgur.com/O5zDc.png
[3]: https://i.stack.imgur.com/Xrxc8.png
[4]: https://i.stack.imgur.com/hwxyw.png
Here you need to find the user in registration_form action, I think this should work
class PagesController < ApplicationController
before_action :authenticate_user!
before_action :set_user, only: [:edit, :registration_form]
def home; end
def registration_form; end
def edit; end
def register_freelancer
#user.update(seller_params)
current_user.freelancer!
redirect_back(fallback_location: root_path)
end
private
def set_user
#user = current_user
end
def seller_params
params.require(:user).permit(:first_name, :last_name, :bio, :cost)
end
end
Then update the form to this
<%= form_with(model: #user, url: registration_form_path), method: :post do |form|%>
<%= form.text_field :first_name, placeholder: "First Name"%>
<%= form.text_field :last_name, placeholder: "Last Name"%>
<%= form.text_field :bio, placeholder: "Bio"%>
<%= form.number_field :cost, placeholder: "Cost per hour in $'s"%>
<%= form.submit %>
<%end%>
Though this is not correct approach how you are trying to update user fields, but here is what you should do to make it works:
Since you have defined these two routes:
get 'registration_form' => 'pages#registration_form'
post 'registration_form' => 'pages#register_freelancer'
These routes don't suppose to have user ID in the URL as a fragment so that you need to pass it explicit:
# add ?id=1 to your route
http://localhost:3000/registration_form?id=1
And then change your action and form:
def registration_form
#user = User.find(params[:id])
end
<%= form_with model: #user, url: registration_form_path(id: #user.id), method: :post do |form|%>
<%= form.text_field :first_name, placeholder: "First Name"%>
<%= form.text_field :last_name, placeholder: "Last Name"%>
<%= form.text_field :bio, placeholder: "Bio"%>
<%= form.number_field :cost, placeholder: "Cost per hour in $'s"%>
<%= form.submit %>
<%end%>
Update:
So that your routes support user ID as a fragment you need to change your routes:
resources :users do
member do
get 'registration_form' => 'pages#registration_form'
post 'registration_form' => 'pages#register_freelancer'
end
end
After this change your will have these URLs:
registration_form_user GET /users/:id/registration_form(.:format)
registration_form_user POST /users/:id/registration_form(.:format)
So you need to change your paths from registration_form to registration_form_user(USER_INSTANSE). You need to replace USER_INSTANSE to user instance you want to fill out registration_form
And change your form
<%= form_with model: #user, url: registration_form_user_path(#user), method: :post do |form|%>
<%= form.text_field :first_name, placeholder: "First Name"%>
<%= form.text_field :last_name, placeholder: "Last Name"%>
<%= form.text_field :bio, placeholder: "Bio"%>
<%= form.number_field :cost, placeholder: "Cost per hour in $'s"%>
<%= form.submit %>
<%end%>

Getting First argument in form cannot contain nil or be empty while trying to allow users to edit their password

I am trying to add a solution to allow users to change their password. I am using devise. And I followed up the third solution from this tutorial.
However after I do everything:
class UsersController < ApplicationController
before_action :authenticate_user!
def edit
#user = current_user
end
def update_password
#user = current_user
if #user.update_with_password(user_params)
# Sign in the user by passing validation in case their password changed
bypass_sign_in(#user)
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, :current_password)
end
end
in routes.rb
resource :user, only: [:edit] do
collection do
patch 'update_password'
end
end
and in the view:
<%= form_for(#user, :url => { :action => "update_password" } ) do |f| %>
<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>
<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 %>
but I get this error First argument in form cannot contain nil or be empty in
= form_for(#user, :url => { :action => 'update_password' } ) do |f|
is there something I have missed? Thanks!

Couldn't find User with id=update_password with Devise

I'm using devise on a Rails application and for various reasons I needed to add a custom password change, using solution 3 from here: https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-edit-their-password
I've looked through various other questions and tried augmenting my routes in a number of ways but the url always comes up /users/update_password (without a parameter passed), or /users/update_password.254 (with a parameter passed). I need it to be /users/254/update_password.
Here is the Users Controller I'm working with (relevant methods are update_password and user_params).
class UsersController < ApplicationController
inherit_resources
load_and_authorize_resource
before_filter :authenticate_user!
def destroy
name = #user.to_s
destroy!(notice: "User #{#user.to_s} was deleted.")
end
def edit
#user = current_user
end
def update_password
#user = User.find(current_user.id)
if #user.update_with_password(user_params)
sign_in #user, :bypass => true
redirect_to root_path
else
render "edit"
end
end
private
def build_resource_params
[params.fetch(:user, {}).permit(:name, :email, :phone_number, :password, :password_confirmation).tap do |p|
p[:institution_pid] = build_institution_pid if params[:user][:institution_pid]
p[:role_ids] = build_role_ids if params[:user][:role_ids]
end]
end
def build_institution_pid
institution = Institution.find(params[:user][:institution_pid])
authorize!(:add_user, institution)
institution.id
end
def build_role_ids
[].tap do |role_ids|
roles = Role.find(params[:user][:role_ids].reject &:blank?)
roles.each do |role|
authorize!(:add_user, role)
role_ids << role.id
end
end
end
def user_params
params.required(:user).permit(:password, :password_confirmation, :current_password)
end
end
This is the relevant portion of routes.rb
devise_for :users
resources :users do
collection do
get 'password'
put 'update_password'
end
end
This is the view I created to go with it:
<div class="page-header">
<h1>Change Password</h1>
</div>
<%= 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="field">
<%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password %>
</div>
<div class="action_container">
<%= f.submit %>
</div>
And this is the link: (currently with a parameter but I've tried without as well)
<li><%= link_to "Change Password", update_password_users_path(current_user) %></li>
When I click that link I get routed to a page that says ActiveRecord::RecordNotFound in UsersController#show, Couldn't find User with id=update_password.
I tried to follow the instructions pretty closely and I've tried to fiddle with the routes a couple times to get it to work and I'm pretty lost at this point. Has anyone seen this before and can help? Thanks!
To achieve what you need, you will have the following routes:
resources :users do
patch 'update_password', on: :collection
get 'edit_password', on: :member
end
Then you'll add a link that would lead user to update password form. The link should look like as follows:
<li><%= link_to "Change Password", edit_password_user_path(current_user) %></li>
The link would lead to users/edit_password.html.erb:
<div class="page-header">
<h1>Change Password</h1>
</div>
<%= 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="field">
<%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password %>
</div>
<div class="action_container">
<%= f.submit %>
</div>
<% end %>
When form is submitted, that would trigger update_password in UsersController. Here is the code for controller:
class UsersController < ApplicationController
def edit_password
#user = current_user
end
def update_password
#user = User.find(current_user.id)
if #user.update_with_password(user_params)
sign_in #user, :bypass => true
redirect_to root_url
else
render "edit_password"
end
end
private
def user_params
params.required(:user).permit(:password, :password_confirmation, :current_password)
end
end

Rails mailboxer gem cannot send message

I am using Mailboxer gem for the messaging function, but as I am very new I am not very sure how to use it. Basically I created the following message controller:
class MessagesController < ApplicationController
before_action :set_message, only: [:new, :create]
def new
#message = Message.new
end
def create
current_user.send_message(#recipient, message_params(:body, :subject))
redirect_to conversations_path
end
private
def set_message
#recipient = User.find(params[:recipient_id])
end
def message_params
params.require(:message).permit(:body, :subject)
end
end
Then my view:
<h1>New Message</h1>
<%= simple_form_for(#message, html: {class: "form-horizontal"}) do |f| %>
<%= f.error_notification %>
<%= f.input :subject %>
<%= f.input :body, as: :text, input_html: { rows: "3"} %>
<div class="form-actions">
<%= f.button :submit, class: "btn btn-primary" %>
</div>
<% end %>
But I can't send message...
(BTW I can send message is the console, and also replace part of the message controller with "current_user.send_message(#recipient, "test", "test")", but definitely not what I want)
Use form_tag instead of form_for
Instead of using form_for, try using form_tag, as this has worked for me:
<%= form_tag("/messages/send_message", method: "post", url: send_message_path) do %>
<%= hidden_field_tag :user_id, "#{#user.id}" %>
<%= text_field_tag :subject, nil, :class => 'form-control', :placeholder => "Subject" %>
<%= text_area_tag :message, nil, :class => 'form-control', :placeholder => "Message" %>
<%= submit_tag "Submit", :class => "btn btn-primary" %>
<% end %>
This would have an action you messages controller like this:
def send_message
#user = User.find(params[:user_id])
#message = params[:message]
#subject = params[:subject]
current_user.send_message(#user, "#{#message}", "#{#subject}")
redirect_to root_path
end
And something like this in you routes file:
post '/messages/send_message', :to => "messages#send_message", :as => "send_message"
Really hope this helps!

undefined method `before_create'

I have a User model and a Company model linked like this:
class User < ActiveRecord::Base
belongs_to :company
accepts_nested_attributes_for :company
end
class Company < ActiveRecord::Base
has_many :users
end
On the sign in page, I want the user to set up both his info (mail, password) and his company info (several fields). So my form looks like this:
<%= simple_form_for #user, :html => { :class => 'form-horizontal' } do |f| %>
<%= f.input :email, :required => true, :placeholder => "user#domain.com" %>
<%= f.input :password, :required => true %>
<%= f.input :password_confirmation, :required => true %>
<h2>Company info</h2>
<%= simple_fields_for :company, :html => { :class => 'form-horizontal' } do |fa| %>
<%= fa.input :name %>
<%= fa.input :url %>
<%= fa.input :description, :as => :text, :input_html => { :cols => 60, :rows => 3 } %>
<%= fa.input :logo %>
<%= fa.input :industry %>
<%= fa.input :headquarters %>
<% end %>
<div class="form-actions">
<%= f.submit nil, :class => 'btn btn-primary' %>
<%= link_to t('.cancel', :default => t("helpers.links.cancel")),
root_url, :class => 'btn' %>
</div>
<% end %>
My user model has a company_id:integer field. So logically, when I sign in the user, the first thing to do is to create the Company before the User and then give to the user creation model the appropriate company_id. So I wrote this:
class UsersController < ApplicationController
before_create :create_company
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
redirect_to root_url, :notice => "Registration successful."
else
render :action => 'new'
end
end
private
def create_company
#company = Company.new(params[:company])
if #company.save
self.company_id = #company.id
else
render :action => 'new'
end
end
end
Problem is: when accessing /users/new I get this error:
undefined method `before_create' for UsersController:Class
What's going wrong? I checked, before_create has not been deprecated, I'm in Rails 3.2.8. This is probably something stupid with my create_company method but I can't figure why...
Thanks a lot for helping!
before_create is a hook method belonging to ActiveRecord
before_filter is a hook method belonging to Controller.
so I suggest you to re-build your code after you make clear which is which. ^_^

Resources