routes are correct, not sure what else is off?
upon "updating" page (when it routes to update) I get the error
param is missing or the value is empty: user
This is my second custom view page for devise the other is working with similar code.
routes-
devise_for :users, controllers: {registrations: 'users/registrations'} as :user do
end
root 'home#home'
get 'users/discovery_settings' => 'users#discovery_settings'
patch 'users/discovery_settings/update' => 'users#update_discovery'
My user controller-
def update_discovery
#user = User.find(current_user.id)
if #user.update(user_params2)
# 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
def user_params2
# NOTE: Using `strong_parameters` gem
params.require(:user).permit(:discovery, :male, :female, :min_age, :max_age)
end
Then my views form_for calls the method
<%= form_for(#user, :url => { :action => "update_discovery" }, html: {class: "form floating-label"}) do |f| %>
Figured this out on my own and posted a blog about it, here was my answer:
Out of all the problems i've had customizing devise this one probably took the longest for me to figure out. A common error you will receive from doing this incorrectly is:
param is missing or the value is empty: user
1st step is to create a controller that inherits the devise controller (essentially overriding it). This should go inside controllers/users and be called registration_controller.rb .
Insert the following code for a secondary customer edit view-
class Users::RegistrationsController < Devise::RegistrationsController
before_filter :configure_permitted_parameters
def NAMEOFVIEW
#user = current_user
if #user
render :NAMEOFVIEW
else
render file: 'public/404', status: 404, formats: [:html]
end
end
also you'll need to sanitize any custom parameters you make in your database
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up) { |u| u.permit(:username, :email, :password, :name, :user_age, :user_gender ) }
devise_parameter_sanitizer.permit(:account_update) { |u| u.permit(:username, :email, :password, :password_confirmation, :current_password, :name, :user_age, :user_gender, :user_bio ) }
end
and finally allow updates without password (by default devise forces this)
protected
def update_resource(resource, params)
resource.update_without_password(params)
end
Under routes:
Rails.application.routes.draw do
devise_for :users, controllers: {registrations: 'users/registrations'}
as :user do
match 'users/NAMEOFVIEWHERE' => 'users/registrations#NAMEOFVIEWHERE', :via => [:get], :as => 'NAMEOFVIEWHERE'
then finally any changes in your view can be done using a form_for or a form_tag, form_for example below:
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put, class: " html classes here" }) do |f| %>
<div class="field">
<%= f.label :Bio %><br />
<%= f.text_area :user_bio, autocomplete: "off", class: "optional html class here", rows: 3, cols: 20, name: "description", placeholder: "About" %>
</div>
<div class="optional button class here">
<button type="submit">Save</button>
</div>
<% end %>
Now restart your rails server and cross your fingers!
Related
routes are correct, not sure what else is off?
upon "updating" page (when it routes to update) I get the error
param is missing or the value is empty: user
This is my second custom view page for devise the other is working with similar code.
routes-
devise_for :users, controllers: {registrations: 'users/registrations'} as :user do end root 'home#home'
get 'users/discovery_settings' => 'users#discovery_settings' patch 'users/discovery_settings/update' => 'users#update_discovery'
My user controller-
def update_discovery
#user = User.find(current_user.id)
if #user.update(user_params2)
# 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
def user_params2
# NOTE: Using `strong_parameters` gem
params.require(:user).permit(:discovery, :male, :female, :min_age, :max_age)
end
Then my views form_for calls the method
<%= form_for(#user, :url => { :action => "update_discovery" }, html: {class: "form floating-label"}) do |f| %>
Figured this out on my own and posted a blog about it, here was my answer:
Out of all the problems i've had customizing devise this one probably took the longest for me to figure out. A common error you will receive from doing this incorrectly is:
param is missing or the value is empty: user
1st step is to create a controller that inherits the devise controller (essentially overriding it). This should go inside controllers/users and be called registration_controller.rb .
Insert the following code for a secondary customer edit view-
class Users::RegistrationsController < Devise::RegistrationsController
before_filter :configure_permitted_parameters
def NAMEOFVIEW
#user = current_user
if #user
render :NAMEOFVIEW
else
render file: 'public/404', status: 404, formats: [:html]
end
end
also you'll need to sanitize any custom parameters you make in your database
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up) { |u| u.permit(:username, :email, :password, :name, :user_age, :user_gender ) }
devise_parameter_sanitizer.permit(:account_update) { |u| u.permit(:username, :email, :password, :password_confirmation, :current_password, :name, :user_age, :user_gender, :user_bio ) }
end
and finally allow updates without password (by default devise forces this)
protected
def update_resource(resource, params)
resource.update_without_password(params)
end
Under routes:
Rails.application.routes.draw do
devise_for :users, controllers: {registrations: 'users/registrations'}
as :user do
match 'users/NAMEOFVIEWHERE' => 'users/registrations#NAMEOFVIEWHERE', :via => [:get], :as => 'NAMEOFVIEWHERE'
then finally any changes in your view can be done using a form_for or a form_tag, form_for example below:
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put, class: " html classes here" }) do |f| %>
<div class="field">
<%= f.label :Bio %><br />
<%= f.text_area :user_bio, autocomplete: "off", class: "optional html class here", rows: 3, cols: 20, name: "description", placeholder: "About" %>
</div>
<div class="optional button class here">
<button type="submit">Save</button>
</div>
<% end %>
Now restart your rails server and cross your fingers!
I am very new to rails and am attempting to get some practice by building a profile page. I have implemented devise and once a user has signed in they can click on a link that displays a profile with information about them. Right now it is just displaying their name, date of birth, and gender. I would like for it to also display an image of them. So I have bundled the paperclip gem and read through some tutorials to try and get it configured. I have gotten the code in place, so that a user can click on 'choose file' and select an image. However when I click 'update' it provides me with an error. I'd like for the image to display on the same show page of their profile.
profiles_controller.rb
class Users::ProfilesController < ApplicationController
def edit
#profile = Profile.create(params[:photo])
end
def create
end
private
def profile_params
params.require(:profile).permit(:photo)
end
end
profiles/edit.html.erb
<h2>Edit Account Profile </h2>
<%= form_for(#profile, url: profiles_edit_path(#profile), html: { :multipart => true }) do |f| %>
<li>
<%= f.label :photo, "Photo" %>
<%= f.file_field :photo %>
</li>
<div class="actions">
<%= f.submit "Update" %>
</div>
<% end %>
<%= link_to "Back", :back %>
registrations/show.html.erb
<%= image_tag #profile.photo.url %>
<br>
<%= #user.email %>
<br>
<%= #user.first_name %>
<%= #user.last_name %>
<br>
<%= #user.date_of_birth %>
<br>
<%= #user.is_female %>
registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
def show
#user = User.find(params[:id])
end
private
def sign_up_params
params.require(:user).permit(:first_name, :last_name, :is_female, :date_of_birth, :email, :password, :password_confirmation)
end
def account_update_params
params.require(:user).permit(:first_name, :last_name, :is_female, :date_of_birth, :email, :password, :password_confirmation, :current_password)
end
end
routes.rb
Rails.application.routes.draw do
devise_for :users, :controllers => { :registrations => 'users/registrations', :profiles => 'users/profiles' }
devise_scope :user do
get 'profiles/edit' => 'users/profiles#edit'
post 'profiles/edit' => 'users/profiles#edit'
get 'users/:id' => 'users/registrations#show', as: :user
end
root to: "home#index"
end
Error after clicking update:
Routing Error
No route matches [PATCH] "/profiles/edit.21"
I appreciate any assistance, and please let me know if any further information is needed.
Try:
patch 'profiles/:id' => 'users/profiles#update'
and form helper should like this:
<%= form_for(#profile, html: { :multipart => true }) do |f| %>
Hope it is helpful for you!!
try adding this route to devise_scope to pass that error
patch 'profiles/edit' => 'users/profiles#edit'
btw, in ProfilesController
creating new Profile should be in create action
in edit action, you should load existed profile and render edit view
Update:
form in edit view will submit data to action update, we need get profile again and update data for it
your routes is not correct, when edit a profile, we should submit to a url look like users/profiles/4/update
you can declare routes as below
devise_for :users, :controllers => { :registrations => 'users/registrations' }
namespace :users do
resources :profiles
end
In update action, you retrieve that profile p = Profile.find(params[:id]) and update it p.photo = params[:photo]; p.save or anything you want
I'm trying to make a custom edit form for devise user, but when I submit the form shell throw me this error:
No route matches [POST] "/profile/12/edit"
Here is my form:
= simple_form_for(:user), html: { method: :put }) do |f|
= f.input :email
= f.input :username
= f.input :phone
= f.input :password, autocomplete: "off", required: false
= f.input :password_confirmation, required: false
= f.input :current_password, required: true
= f.button :submit, 'Update'
Here is my profile_controller
class ProfileController < ApplicationController
def show
#client = Client.find(params[:id])
end
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
if #user.update_attributes(params[:user])
redirect_to root_path
end
end
end
And my routes.rb :
Rails.application.routes.draw do
root 'home#index'
devise_for :users
resources :profile
end
What I'm doing wrong?
This is how I would do it:
= simple_form_for #user,
:url => url_for(:action => 'edit', :controller => 'profiles'),
:method => 'put' do |f|
Here you are submitting a PUT (update) request to the edit action of your ProfilesController.
Also notice the difference here between ProfileController and what I wrote ProfilesController. The convention in Rails and as for DHH is that your model names should be singular and your controller plural.
model
class Profile < ActiveRecord::Base
end
controller
class ProfilesController < ApplicationController
end
Replace:
= simple_form_for(:user), html: { method: :put }) do |f|
with:
= simple_form_for #user, method: :put, url: "/profile" do |f|
Some of the mistakes:
if you want to edit an object, provide it, not a mere symbol
the path must be adjusted to point to /profile
method not an html property, it creates a hidden field intercepted by rails in order to know the received post should be understood as a put
we feel like there is a typo: controller should be pluralized
There are similar questions but I've gone over them and none of them have applied.
I am using Devise and Devise invitations. Rails 3.2.6.
The tricky thing is I have two user models. User and a single table inheritance setup where Artist inherits from User. I have two invitations controllers to allow sending invitations separately to both Users and Artists.
The issue right now is that artists are not able to accept their invitations. Upon form submit of updating their password, they get a 406 unacceptable error.
Relevant Code:
Routing:
devise_for :users,
:class_name => User,
:controllers => { :invitations => 'user/invitations' }
namespace :artist do
# Special route for devise, artists invitation
devise_scope :user do
resource :invitation, :controller => :invitations, :only => [:create, :new, :update] do
get :accept, :action => :edit
end
end
end
Artist invitations controller
class Artist::InvitationsController < Devise::InvitationsController
respond_to :html
# PUT /resource/invitation
def update
self.resource = Artist.accept_invitation!(params[resource_name])
if resource.errors.empty?
resource.pending
flash[:notice] = "Welcome, complete your artist agreement to get started"
sign_in(:user, resource)
respond_with resource, :location => after_accept_path_for(resource)
else
respond_with_navigational(resource){ render :edit }
end
end
end
Form description. edit.html.erb.
<%= form_for resource, :as => resource_name, :url => artist_invitation_path(resource_name), :html => { :method => :put } do |f| %>
<%= f.hidden_field :invitation_token %>
<%= f.label :password, class: 'control-label' %>
<%= f.password_field :password, :placeholder => 'Enter a password' %>
<%= f.label :password_confirmation, class: 'control-label' %>
<%= f.password_field :password_confirmation, :placeholder => 'Confirm your password' %>
<%= f.submit "Set my password", :'data-disable-with' => "Hang on..." %>
<% end %>
Accept headers
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Content-Length:236
Content-Type:application/x-www-form-urlencoded
Returns
Request URL:http://localhost:3000/artist/invitation.user
Request Method:POST
Status Code:406 Not Acceptable
I can see that something in the format must be off because of the response adding in that .user to the end. I can not for the life of me see why or where that is happening. Please let me know if there's any info I left out which could help.
Got it, finally.
The key is to look precisely at what resource_name is giving you throughout the form and controller actions. In my case it continued to fallback to :user when it needed to be :artist and as Frost mentioned in a comment, the generated form html changes greatly if you pay attention to where resource_name is used. The update action in the controller needed to be overridden to use :artist directly and the form_for needed to be tweaked to remove resource_name from arguments and the :as argument.
I've got a page which loads at home.html.erb and is controlled by the pages controller.
In the page, I have a form which is a single field that will be used to take email addresses.
The error I'm getting is:
undefined method `signups_path'
Here's my code for your reference, I'm not sure how exactly to define where the route is that it goes.
Home.html.erb contains this form:
<%= form_for(#signup) do |f| %>
<div class="field">
<%= f.label :email %><br />
<%= f.text_field :email %>
</div>
<div class="actions">
<%= f.submit "Enter" %>
</div>
<% end %>
The Pages controller contains:
class PagesController < ApplicationController
def home
#title = "Open Domain - Liberate your domains from obscurity"
#signup = Signup.new
end
end
The Signup controller contains:
class SignupController < ApplicationController
def show
#signup = Signup.new
end
def new
end
def create
#signup = Signup.new(params[:signup])
if #signup.save
else
render 'new'
end
end
end
And the signup model contains:
class Signup < ActiveRecord::Base
attr_accessible :email
email_regex = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates(:email, :presence => true,
:length => {:maximum => 40},
:format => {:with => email_regex})
end
Any help would be hugely appreciated it. I have a feeling this is a tiny problem and I'm a beginning dev. Thanks!
The form_for(#signup) is trying to build a route to POST to. If you don't have a named route in your routes.rb, you'll get this error. Try:
routes.rb
post '/signup', :to=>"signup#create", :as=>"signups"
this basically says: When a POST to the '/signup' path is requested, route it to the create action in the signup controller. Also, make a helper to this path accessible with the name: "signups_path"
You can replace your form_for tag with this:
<%= form_for #signup, :url => { :action => "create" } do |f| %>
This will post it to "signup/create".