I couldn't update user information following suggested procedures on devise's own page. When I click the Update button in the form it redirects back to to user/show without updating anything. The logs on console shows the RegistrationsController#update action was called instead the update_resource action from my custom RegistrationController.
logs:
Started PATCH "/users" for 127.0.0.1 at 2016-12-11 18:34:51 +0200
Processing by RegistrationsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"5vqLuQKyuJIoCx0mYfBUhIQmvS0Il5jy+ty1f2XDsehJM4i3M8mMPK5tdPpVQ6MFHIj05ZcRKO7rhlxroM75pQ==", "user"=>{"first_name"=>"Birhanu", "last_name"=>"Hailemariam2", "email"=>"birhanuh4#gmail.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "current_password"=>"[FILTERED]"}, "commit"=>"Update User"}
User Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
Account Load (0.4ms) SELECT "public"."accounts".* FROM "public"."accounts" WHERE "public"."accounts"."subdomain" = $1 LIMIT 1 [["subdomain", "test3"]]
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 1]]
(0.3ms) BEGIN
(0.7ms) SELECT COUNT(*) FROM "users"
(0.3ms) ROLLBACK
Redirected to http://test3.lvh.me:3000/users/1
Completed 302 Found in 120ms (ActiveRecord: 4.5ms)
Started GET "/users/1" for 127.0.0.1 at 2016-12-11 18:34:51 +0200
views/devise/registrations/edit.slim
= simple_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f|
= f.input :first_name, autofocus: true
= f.input :last_name, autofocus: true
= f.input :email, autofocus: true
- if devise_mapping.confirmable? && resource.pending_reconfirmation?
div
|Currently waiting confirmation for: = resource.unconfirmed_email
.form-actions.col-sm-offset-3.m-b-xs
i
|(leave blank if you don't want to change it)
= f.input :password, autocomplete: "off"
= f.input :password_confirmation, autocomplete: "off"
.form-actions.col-sm-offset-3.m-b-xs
i
|(we need your current password to confirm your changes)
= f.input :current_password, autocomplete: "off"
.form-actions.form.col-sm-offset-3
=> link_to I18n.t('button.cancel'), :back, class: 'btn btn-primary btn-outline'
= f.button :submit, class: 'btn btn-primary'
controller/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
protected
def update_resource(resource, user_params)
resource.update_with_password(user_params)
end
def after_update_path_for(resource)
current_account
end
end
controllers/application_controller.rb
class ApplicationController < ActionController::Base
.
.
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:accept_invitation, keys: [:first_name, :last_name])
devise_parameter_sanitizer.permit(:account_update, keys: [:first_name, :last_name, :email, :password, :password_confirmation,
:current_password])
end
.
.
end
routes:
devise_for :users, controllers: { registrations: 'registrations' }
I have managed to find what was causing the issue. It is because I have a private method that was returning false value to before_save ActiveRecord callback. Fact source: enter link description here
Previous version:
private
def set_admin
self.admin = User.count == 0
end
It should be changed to return nil in case of false value.
private
def set_admin
self.admin = User.count == 0
nil
end
Now everything works, I can update user info!
Related
I am new to ruby on rails and I have a problem to get parameters of type datetime and pass them to edit page. The idea is that there is a table called week which contains information about courses and the starting week(date) of each course, user could create and edit these weeks. I have a form page for edit and create the courses' name and their start date. I use f.datetime_select for getting start date of each course from user. here is the form and index page:
index(first) page:
%tbody
- #weeks.each do |week|
%tr
%td= week.course ? week.course.name : "unassigned"
%td= week.start.strftime("%a, %d.%m.%Y").to_s
%td= link_to 'Edit', edit_week_path(week)
%td= link_to 'Destroy', week, :method => :delete, :data => { :confirm => 'Are you sure?' }
form page:
= form_for #week do |f|
- if #week.errors.any?
#error_explanation
%h2= "#{pluralize(#week.errors.count, "error")} prohibited this week from being saved:"
%ul
- #week.errors.full_messages.each do |msg|
%li= msg
.form-group
= f.label :course
= #course.name
.form-group.form-inline
= f.label :start
= f.datetime_select :start, {order: [:month, :day, :year], prompt: { day: 'Select day', month: 'Select month', year: 'Select year' }}, {required: true}
.actions
= f.submit 'Save', :class => "btn btn-primary"
There is no problem by creating a new date but I have problem in editting the dates which user save in the above form. actually when the user click on edit page, datetime error is shown as follows:
F, [2018-01-25T21:16:43.454087 #819] FATAL -- :
ActionView::Template::Error (undefined method `to_datetime' for 0:Fixnum):
11: = #course.name
12: .form-group.form-inline
13: = f.label :start
14: = f.datetime_select :start, {order: [:month, :day, :year], prompt: { day: 'Select day', month: 'Select month', year: 'Select year' }}, {required: true}
15: //= f.date_select :start, {}, { :class => "form-control" }
16: .actions
17: = f.submit 'Save', :class => "btn btn-primary"
app/views/weeks/_form.html.haml:14:in `block in _app_views_weeks__form_html_haml___241486880657666967_43852860'
app/views/weeks/_form.html.haml:1:in `_app_views_weeks__form_html_haml___241486880657666967_43852860'
app/views/weeks/edit.html.haml:3:in `_app_views_weeks_edit_html_haml___597540861062441854_41928920'
and here is the controller file:
class WeeksController < ApplicationController
before_filter :authenticate_user!
before_filter :admincheck
before_action :set_week, only: [:show, :edit, :update, :destroy]
# GET /weeks
# GET /weeks.json
def index
#weeks = #course.weeks
end
# GET /weeks/new
def new
#week = Week.new
end
# GET /weeks/1/edit
def edit
end
def show
end
# POST /weeks
# POST /weeks.json
def create
#week = Week.new(week_params.merge(course_id: #course.id))
if #week.save
redirect_to '/weeks'
else
render action: 'new'
end
end
# PATCH/PUT /weeks/1
# PATCH/PUT /weeks/1.json
def update
if #week.update(week_params)
redirect_to '/weeks'
else
render action: 'edit'
end
end
# DELETE /weeks/1
# DELETE /weeks/1.json
def destroy
#week.destroy
redirect_to '/weeks'
end
private
# Use callbacks to share common setup or constraints between actions.
def set_week
#week = Week.find(params[:id])
end
list through.
def week_params
params.require(:week).permit(:start,:course_id)
end
end
this is the definition of table in schema.rb:
create_table "weeks", force: true do |t|
t.datetime "start"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "course_id"
end
any help would be appreciated :)
In case this is (or was) a rails between 4.0.0 and 4.0.3: this is a known bug that was fixed in 4.0.4.
So the best solution in that case is simply to upgrade rails.
I'm on rails 4 and using carrierwave, and I'm trying let users upload photos that belong to specific objects. The parent object is Property, and the child object is Photo. I did this with an eye towards allowing a Property to have multiple photos.
I would like to be able to upload a photo while on the Property edit page. The uploaded photo will have a foreign key that relates to the property_id so I can identify which property it belongs to (hence the hidden field).
My problem is that I keep getting an "Unpermitted parameter: photos" message in my logs that's keeping me from creating the Photo object.
My form looks like this
<%= form_for #property, html: { multipart: true } do |f| %>
<%= render "property_form_fields", f: f %>
<%= f.fields_for :photos do |photo| %>
<p>Add photos:</p>
<%= photo.file_field :photo_file_name%>
<%= photo.hidden_field :property_id, :value => #property.id%>
<% end %>
<%= f.submit "Update property", class: 'btn btn-default' %>
<% end %>
Photo model:
class Photo < ActiveRecord::Base
belongs_to :property
mount_uploader :photo_file_name, PhotoUploader
validate :picture_size
private
# Validates the size of an uploaded picture.
def picture_size
if picture.size > 5.megabytes
errors.add(:picture, "should be less than 5MB")
end
end
end
Property model
class Property < ActiveRecord::Base
has_many :photos
end
Here is my Property Controller
def edit
#property = Property.find(params[:id])
#photos = Photo.where(:property_id => #property.id)
end
def update
#property = Property.find(params[:id])
if #property.update_attributes(property_params)
flash[:success] = "Property was successfully updated."
redirect_to properties_path
else
flash[:error] = "Property was not created"
render edit_property_path
end
private
def property_params
params.require(:property).permit(:property_name, photos_attributes: [:id, :photo_file_name,:property_id])
end
end
Here are my logs when I try to add a photo
Started PATCH "/properties/19" for 108.41.84.27 at 2016-07-08 19:59:24 +0000
Processing by PropertiesController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"ucP...", "property"=>{"property_name"=>"abc", "photos"=>{"photo_file_name"=>#<ActionDispatch::Http::UploadedFile:0x007fe11f0a5598 #tempfile=#<Tempfile:/home/ubuntu/workspace/RackMultipart20160708-6915-1havz2i.jpg>, #original_filename="1554439_686460264746128_2054601640279902551_n.jpg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"property[photos][photo_file_name]\"; filename=\"1554439_686460264746128_2054601640279902551_n.jpg\"\r\nContent-Type: image/jpeg\r\n">, "property_id"=>"19"}}, "commit"=>"Update property", "id"=>"19"}
Manager Load (0.3ms) SELECT "managers".* FROM "managers" WHERE "managers"."id" = ? ORDER BY "managers"."id" ASC LIMIT 1 [["id", 1]]
Property Load (0.2ms) SELECT "properties".* FROM "properties" WHERE "properties"."id" = ? LIMIT 1 [["id", 19]]
Unpermitted parameter: photos
(0.1ms) begin transaction
(0.1ms) commit transaction
Redirected to https://project-apple-mcl282.c9users.io/properties
Completed 302 Found in 12ms (ActiveRecord: 0.7ms)
your Property model needs to accept nested attributes for photos:
class Property < ActiveRecord::Base
has_many :photos
accepts_nested_attributes_for :photos
end
Hi I am attempting to use act_as_taggable ruby gem and have followed the github guide and a recent tutorial as well as checked stack overflow for advice. My code all seems to be correct but when I attempt to save tags via my form partial or via the rails console they do not save to the database.
Below relevant code excerpts.
Thanks in advance for any help!
post.rb
class Post < ActiveRecord::Base
acts_as_taggable
acts_as_taggable_on :tags
validates :title, presence: true, length: {minimum: 5}
validates :body, presence: true
extend FriendlyId
friendly_id :title, use: :slugged
end
post_controller.rb
class PostsController < ApplicationController
before_action :find_post, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
def index
if params[:tag].present?
#posts = Post.tagged_with(params[:tag]).paginate(:page => params[:page], :per_page => 10)
else
#posts = Post.all.order('created_at DESC').paginate(page: params[:page], per_page: 10)
end
end
def new
#post = Post.new
end
def show
end
def create
#post = Post.new(post_params)
if #post.save
redirect_to #post, notice: "Article succesfully saved!"
else
render 'new', notice: "Try Again. I was unable to save your post."
end
end
def edit
end
def update
if #post.update(params[:post].permit(:title, :body))
redirect_to #post, notice: "Article succesfully edited!"
else
render 'edit'
end
end
def destroy
#post.destroy
redirect_to posts_path
end
private
def post_params
params.require(:post).permit(:title, :body, :slug, :tag_list => [])
end
def find_post
#post = Post.friendly.find(params[:id])
end
end
routes.rb
Rails.application.routes.draw do
devise_for :users, :skip => :registrations
root 'pages#home'
resources :posts
resources :portfolios
get 'tags/:tag', to: 'posts#index', as: :tag
end
_form.html.erb
<%= form_for #post do |f| %>
<% if #post.errors.any? %>
<div id="errors">
<h2><%= pluralize(#post.errors.count, "error") %> prevented this post from saving:</h2>
<ul>
<% #post.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.label :title %><br>
<%= f.text_field :title, class: 'form-control form-control-lg' %><br>
<br>
<%= f.label :body %><br>
<%= f.text_area :body, class: 'form-control form-control-lg', :rows => "10" %><br>
<br>
<%= f.label :tag_list, "Tags (separated by commas)" %>
<%= f.text_field :tag_list, class: 'form-control' %>
<br>
<%= f.submit %>
<% end %>
excerpt from show.html.erb
<% #post.tags.any? %>
<% #post.tags.each do |tag| %>
<li><a href="#">
<%= link_to tag.name, tag_path(tag.name) %>
</a></li>
<% end %>
Params log for _form as requested by Pavan:
Started PATCH "/posts/my-third-post-with-tags" for ::1 at 2015-09-23 15:56:36 +1000
Processing by PostsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"GwLMImKSDyhPt77nI+fhIkF4QVsFxMen851wjcVorrxOCdU+TcRKIZv1im4/oNx7DERYCI91vE9YDjvSda7MAg==", "post"=>{"title"=>"My third post with tags", "body"=>"to update your local repository to the newest commit, execute\r\ngit pull\r\nin your working directory to fetch and merge remote changes.\r\nto merge another branch into your active branch (e.g. master), use\r\ngit merge <branch>\r\nin both cases git tries to auto-merge changes. Unfortunately, this is not always possible and results in conflicts. You are responsible to merge those conflicts manually by editing the files shown by git. After changing, you need to mark them as merged with\r\ngit add <filename>\r\nbefore merging changes, you can also preview them by using\r\ngit diff <source_branch> <target_branch>", "tag_list"=>"tag, css"}, "commit"=>"Update Post", "id"=>"my-third-post-with-tags"}
Post Load (0.1ms) SELECT "posts".* FROM "posts" WHERE "posts"."slug" = ? ORDER BY "posts"."id" ASC LIMIT 1 [["slug", "my-third-post-with-tags"]]
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
Unpermitted parameter: tag_list
(0.0ms) begin transaction
(0.0ms) commit transaction
Redirected to http://localhost:3000/posts/my-third-post-with-tags
Completed 302 Found in 4ms (ActiveRecord: 0.3ms)
Started GET "/posts/my-third-post-with-tags" for ::1 at 2015-09-23 15:56:36 +1000
Processing by PostsController#show as HTML
Parameters: {"id"=>"my-third-post-with-tags"}
Post Load (0.1ms) SELECT "posts".* FROM "posts" WHERE "posts"."slug" = ? ORDER BY "posts"."id" ASC LIMIT 1 [["slug", "my-third-post-with-tags"]]
ActsAsTaggableOn::Tag Exists (0.1ms) SELECT 1 AS one FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."taggable_id" = ? AND "taggings"."taggable_type" = ? AND "taggings"."context" = ? LIMIT 1 [["taggable_id", 2], ["taggable_type", "Post"], ["context", "tags"]]
ActsAsTaggableOn::Tag Load (0.1ms) SELECT "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."taggable_id" = ? AND "taggings"."taggable_type" = ? AND "taggings"."context" = ? [["taggable_id", 2], ["taggable_type", "Post"], ["context", "tags"]]
Rendered posts/show.html.erb within layouts/application (3.2ms)
Rendered layouts/_header.html.erb (496.3ms)
Rendered devise/shared/_links.html.erb (0.2ms)
Rendered devise/sessions/_new.html.erb (4.6ms)
Rendered layouts/_slideoutpanels.html.erb (460.2ms)
Rendered layouts/_footer.html.erb (0.0ms)
Completed 200 OK in 1486ms (Views: 1484.3ms | ActiveRecord: 0.2ms)
Your error is from PostsController#update as HTML
In controller you don;t permit tag_list
#post.update(params[:post].permit(:title, :body))
I'm trying to give provide a series of links that when selected will update a corresponding user's parameter to that which is supplied by the link without rendering a form. The only problem I'm running into is that when it calls the update method I get: param is missing or the value is empty: user.
update method
def update
#user = User.find(params[:id])
if #user.update(user_params)
redirect_to list_path
flash[:success] = "User updated"
else
redirect_to list_path
flash[:alert] = "User not updated"
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password,
:password_confirmation, :title, :role, :address, :phone)
end
link_to
<% User.all.each do |user| %>
<% if user.role == "new" %>
<tr>
<td><%= user.name %></td>
<td><%= user.title %></td>
<td><%= user.role %></td>
<td><%= link_to "Admin", update_user_path(id: user.id, :role => "admin"), :method => :put %> / <%= link_to "Moderator", '#' %> / <%= link_to "Member", '#' %> / <%= link_to "Other", '#' %></td>
</tr>
<% end %>
<% end %>
param.inspect
{"_method"=>"put",
"authenticity_token"=>"AUcV1swtGmRuDelTzLkbLd9Gmj6+phnHaSFRqrvDyETLoxNUQSaAgkes4ViWXoAZ33K5NZojVz9XdgIIsqJblA==",
"id"=>"2",
"role"=>"admin"}
From what I've found the params.inspect should have something like [:user] => before all the parameters listed, but I cannot figure out why it is not nor can I successfully find a way to clarify.
error:
param is missing or the value is empty: user
def user_params
**params.require(:user).permit(:name, :email, :password,**
:password_confirmation, :title, :role, :address, :phone)
end
end
Log after link select
Started PUT "/update_user?id=4&role=admin" for 97.78.175.155 at 2015-06-30 15:51:47 +0000
Cannot render console from 97.78.175.155! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by UsersController#update as HTML
Parameters: {"authenticity_token"=>"m+LcLOBL5NBXHQXD19o45/iV07/V1HiAXpykV+NiXIpRBtqubUB+Nn68DciNPaPT+KHwtPFRNnhgy/f16gPPWg==", "id"=>"4", "role"=>"admin"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 4]]
Unpermitted parameters: _method, authenticity_token, id
(0.2ms) begin transaction
User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE (LOWER("users"."email") = LOWER('qwerty#poster.com') AND "users"."id" != 4) LIMIT 1
(0.1ms) rollback transaction
Redirected to https://rails-tutorial-hougthonbrad.c9.io/list
Completed 302 Found in 11ms (ActiveRecord: 0.7ms)
Started GET "/list" for 97.78.175.155 at 2015-06-30 15:51:47 +0000
Cannot render console from 97.78.175.155! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by UsersController#list as HTML
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
User Load (0.5ms) SELECT "users".* FROM "users"
Rendered users/list.html.erb within layouts/application (3.4ms)
Completed 200 OK in 172ms (Views: 165.1ms | ActiveRecord: 0.7ms)
Change your update action to the below.
def update
#user = User.find(params[:id])
if #user.update(user_params)
redirect_to list_path
flash[:success] = "User updated"
else
redirect_to list_path
flash[:alert] = "User not updated"
end
end
Update #1:
Looking at your params, you need to change your user_params like the below.
def user_params
params.require(:user).permit(:id, :name, :email, :password, :password_confirmation, :title, :role, :address, :phone)
end
Update #2:
Try changing your link_to to the below
<%= link_to "Admin", update_user_path(user, user: {:id => user.id, :role => "admin"}), :method => :put %>
You have params.require(:user) within your user_params.
That user hash is usually generated by form_for.
I would suggest to render a form with all fields hidden except the submit button for your use case.
I am experiencing an issue with validating our terms of service checkbox using devise and simple form.
User Model
validates_acceptance_of :terms, :allow_nil => false, :message => :terms_not_accepted, :on => :create
Registration View
= f.label :terms, "I agree to the #{link_to 'Terms of Service', "http://britevid.com/terms_of_service",:remote => true}.".html_safe, {class: "checkbox inline"}
= f.check_box :terms
= f.button :submit, 'Sign up', :class => 'btn btn-success'
Application Controller
def update_sanitized_params
devise_parameter_sanitizer.for(:sign_up) {|u| u.permit(:first_name, :last_name, :company, :phone_number, :website, :content_description, :address, :city, :state, :zip_code, :country, :paypal_email, :time_zone, :email, :current_password, :password, :password_confirmation, :terms)}
devise_parameter_sanitizer.for(:account_update) {|u| u.permit(:first_name, :last_name, :company, :phone_number, :website, :content_description, :address, :city, :state, :zip_code, :country, :paypal_email, :time_zone, :email, :current_password, :password, :password_confirmation)}
end
Started POST "/users" for 127.0.0.1 at 2014-03-21 07:19:24 -0500
Processing by RegistrationsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"[FILTERED]", "user"=>{"first_name"=>"jeff", "last_name"=>"smith", "email"=>"jeffsmith#lol.com", "company"=>"test", "phone_number"=>"453234562", "website"=>"", "content_description"=>"test", "address"=>"1st ave", "city"=>"big city", "state"=>"California", "country"=>"United States", "zip_code"=>"095610", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "terms"=>"0"}, "commit"=>"Sign up"}
(0.2ms) BEGIN
User Exists (0.1ms) SELECT 1 AS one FROM `users` WHERE `users`.`email` = BINARY 'jeffsmith#lol.com' LIMIT 1
(0.1ms) ROLLBACK
Rendered devise/registrations/new.html.haml within layouts/pages (46.2ms)
Rendered layouts/shared/_external_header.html.haml (0.4ms)
Completed 200 OK in 157ms (Views: 67.7ms | ActiveRecord: 0.4ms)
You have setup a validation on terms
validates_acceptance_of :terms, :allow_nil => false, :message => :terms_not_accepted, :on => :create
So, its mandatory to check the terms checkbox while creating a new User. If you don't select the checkbox then your validation fails and you get the error. And ofcourse user record doesn't get saved.
As per the server log, while submitting the form you didn't select the terms checkbox as "terms"=>"0"(in params hash).
Make sure that you select the terms before submitting the form.