uninitialized constant ApplicationMailer - ruby-on-rails

I'm trying to make a contact form work by following this tutorial, but I keep having the error : uninitialized constant ApplicationMailer after i submit the form.
the traces give the following informations:
app/mailers/message_mailer.rb:1:in <top (required)>'
app/controllers/messages_controller.rb:9:in create'
actionpack (4.2.5) lib/action_controller/metal/implicit_render.rb:4:in send_action'
actionpack (4.2.5) lib/abstract_controller/base.rb:198:in process_action'
actionpack (4.2.5) lib/action_controller/metal/rendering.rb:10:in process_action'
actionpack (4.2.5) lib/abstract_controller/callbacks.rb:20:in block in process_action'
activesupport (4.2.5) lib/active_support/callbacks.rb:117:in call'
activesupport (4.2.5) lib/active_support/callbacks.rb:117:in call'
activesupport (4.2.5) lib/active_support/callbacks.rb:555:in block (2 levels) in compile'
activesupport (4.2.5) lib/active_support/callbacks.rb:505:in call'
activesupport (4.2.5) lib/active_support/callbacks.rb:505:in call'
activesupport (4.2.5) lib/active_support/callbacks.rb:92:in __run_callbacks__'
activesupport (4.2.5) lib/active_support/callbacks.rb:778:in _run_process_action_callbacks'`
Here are the file i have :
controllers/messages_controller.rb
class MessagesController < ApplicationController
def new
#message = Message.new
end
def create
#message = Message.new(message_params)
if #message.valid?
MessageMailer.message_me(#message).deliver_now
redirect_to new_message_path, notice: "Thankyou for your message."
else
render :new
end
end
private
def message_params
params.require(:message).permit(:name, :email, :subject, :content)
end
end
models/message.rb
class Message
include ActiveModel::Model
attr_accessor :name, :email, :subject, :content
validates :name, :email, :subject, :content, presence: true
end
mailers/message_mailer.rb
class MessageMailer < ApplicationMailer
default :to => "jd.levarato#gmail.com"
def message_me(msg)
#msg = msg
mail from: #msg.email, subject: #msg.subject, body: #msg.content
end
end

You have to create ApplicationMailer class that inherits from ActionMailer::Base.
application_mailer.rb
class ApplicationMailer < ActionMailer::Base
default from: 'from#exmaple.com'
layout 'mailer'
end
Or you can simply inherit ActionMailer::Base to your MessageMailer
class MessageMailer < ActionMailer::Base
default :to => "jd.levarato#gmail.com"
def message_me(msg)
#msg = msg
mail from: #msg.email, subject: #msg.subject, body: #msg.content
end
end

Related

Rails: :save returns NoMethodError

I am programming a small rails api for practice. The goal is to POST some data and then save it (after further processing) in a database. The object is being created successfuly. On the save method appears an error which I cannot explain:
NoMethodError (undefined method `[]' for nil:NilClass): app/controllers/api/v1/calculations_controller.rb:19:in `create'
It appears in the :create method (on POST):
# POST /calculations
def create
#calculation = Calculation.new(calculation_params)
if #calculation.save # <- This is line 19
render json: #calculation, status: :created, location: #calculation
else
render json: #calculation.errors, status: :unprocessable_entity
end
end
The model looks like this:
require 'digest'
class Calculation < ApplicationRecord
attr_reader :value, :hash_value, :algorithm, :timestamp
##known_algorithms = ['SHA2_256', 'SHA2_384', 'SHA2_512']
def initialize (params)
#value = params[:value]
#algorithm = params[:algorithm]
validate!
#hash_value, #timestamp = digest
end
private
def digest
case #algorithm
when 'SHA2_256'
result = Digest::SHA2.hexdigest(#value)
when 'SHA2_384'
result = Digest::SHA2.new(384).hexdigest(#value)
when 'SHA2_512'
result = Digest::SHA2.new(512).hexdigest(#value)
end
return result, DateTime.now
end
def validate!
raise ArgumentError.new('Value cannot be empty or NIL!') if #value.nil? or #value.empty?
raise ArgumentError.new('Unknown hashing algorithm!') unless ##known_algorithms.include? #algorithm
end
end
Why does the NoMethodError appear? Did I override some important part in the model class?
Full stack trace as requested:
/home/pbz/.gem/ruby/2.5.0/gems/activerecord-5.2.2/lib/active_record/transactions.rb:424:in `clear_transaction_record_state'
/home/pbz/.gem/ruby/2.5.0/gems/activerecord-5.2.2/lib/active_record/transactions.rb:330:in `ensure in rollback_active_record_state!'
/home/pbz/.gem/ruby/2.5.0/gems/activerecord-5.2.2/lib/active_record/transactions.rb:330:in `rollback_active_record_state!'
/home/pbz/.gem/ruby/2.5.0/gems/activerecord-5.2.2/lib/active_record/transactions.rb:309:in `save'
/home/pbz/.gem/ruby/2.5.0/gems/activerecord-5.2.2/lib/active_record/suppressor.rb:44:in `save'
/home/pbz/RubymineProjects/hasher_api/app/controllers/api/v1/calculations_controller.rb:20:in `create'
/home/pbz/.gem/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action'
/home/pbz/.gem/ruby/2.5.0/gems/actionpack-5.2.2/lib/abstract_controller/base.rb:194:in `process_action'
/home/pbz/.gem/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_controller/metal/rendering.rb:30:in `process_action'
/home/pbz/.gem/ruby/2.5.0/gems/actionpack-5.2.2/lib/abstract_controller/callbacks.rb:42:in `block in process_action'
/home/pbz/.gem/ruby/2.5.0/gems/activesupport-5.2.2/lib/active_support/callbacks.rb:132:in `run_callbacks'
/home/pbz/.gem/ruby/2.5.0/gems/actionpack-5.2.2/lib/abstract_controller/callbacks.rb:41:in `process_action'
/home/pbz/.gem/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_controller/metal/rescue.rb:22:in `process_action'
/home/pbz/.gem/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_controller/metal/instrumentation.rb:34:in `block in process_action'
/home/pbz/.gem/ruby/2.5.0/gems/activesupport-5.2.2/lib/active_support/notifications.rb:168:in `block in instrument'
/home/pbz/.gem/ruby/2.5.0/gems/activesupport-5.2.2/lib/active_support/notifications/instrumenter.rb:23:in `instrument'
/home/pbz/.gem/ruby/2.5.0/gems/activesupport-5.2.2/lib/active_support/notifications.rb:168:in `instrument'
/home/pbz/.gem/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_controller/metal/instrumentation.rb:32:in `process_action'
/home/pbz/.gem/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_controller/metal/params_wrapper.rb:256:in `process_action'
/home/pbz/.gem/ruby/2.5.0/gems/activerecord-5.2.2/lib/active_record/railties/controller_runtime.rb:24:in `process_action'
/home/pbz/.gem/ruby/2.5.0/gems/actionpack-5.2.2/lib/abstract_controller/base.rb:134:in `process'
/home/pbz/.gem/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_controller/metal.rb:191:in `dispatch'
/home/pbz/.gem/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_controller/metal.rb:252:in `dispatch'
/home/pbz/.gem/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/routing/route_set.rb:52:in `dispatch'
/home/pbz/.gem/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/routing/route_set.rb:34:in `serve'
/home/pbz/.gem/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/journey/router.rb:52:in `block in serve'
/home/pbz/.gem/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/journey/router.rb:35:in `each'
/home/pbz/.gem/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/journey/router.rb:35:in `serve'
/home/pbz/.gem/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/routing/route_set.rb:840:in `call'
/home/pbz/.gem/ruby/2.5.0/gems/rack-2.0.6/lib/rack/etag.rb:25:in `call'
/home/pbz/.gem/ruby/2.5.0/gems/rack-2.0.6/lib/rack/conditional_get.rb:38:in `call'
/home/pbz/.gem/ruby/2.5.0/gems/rack-2.0.6/lib/rack/head.rb:12:in `call'
/home/pbz/.gem/ruby/2.5.0/gems/activerecord-5.2.2/lib/active_record/migration.rb:559:in `call'
/home/pbz/.gem/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/middleware/callbacks.rb:28:in `block in call'
/home/pbz/.gem/ruby/2.5.0/gems/activesupport-5.2.2/lib/active_support/callbacks.rb:98:in `run_callbacks'
/home/pbz/.gem/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/middleware/callbacks.rb:26:in `call'
/home/pbz/.gem/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/middleware/executor.rb:14:in `call'
/home/pbz/.gem/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/middleware/debug_exceptions.rb:61:in `call'
/home/pbz/.gem/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
/home/pbz/.gem/ruby/2.5.0/gems/railties-5.2.2/lib/rails/rack/logger.rb:38:in `call_app'
/home/pbz/.gem/ruby/2.5.0/gems/railties-5.2.2/lib/rails/rack/logger.rb:26:in `block in call'
/home/pbz/.gem/ruby/2.5.0/gems/activesupport-5.2.2/lib/active_support/tagged_logging.rb:71:in `block in tagged'
/home/pbz/.gem/ruby/2.5.0/gems/activesupport-5.2.2/lib/active_support/tagged_logging.rb:28:in `tagged'
/home/pbz/.gem/ruby/2.5.0/gems/activesupport-5.2.2/lib/active_support/tagged_logging.rb:71:in `tagged'
/home/pbz/.gem/ruby/2.5.0/gems/railties-5.2.2/lib/rails/rack/logger.rb:26:in `call'
/home/pbz/.gem/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
/home/pbz/.gem/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/middleware/request_id.rb:27:in `call'
/home/pbz/.gem/ruby/2.5.0/gems/rack-2.0.6/lib/rack/runtime.rb:22:in `call'
/home/pbz/.gem/ruby/2.5.0/gems/activesupport-5.2.2/lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call'
/home/pbz/.gem/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/middleware/executor.rb:14:in `call'
/home/pbz/.gem/ruby/2.5.0/gems/actionpack-5.2.2/lib/action_dispatch/middleware/static.rb:127:in `call'
/home/pbz/.gem/ruby/2.5.0/gems/rack-2.0.6/lib/rack/sendfile.rb:111:in `call'
/home/pbz/.gem/ruby/2.5.0/gems/railties-5.2.2/lib/rails/engine.rb:524:in `call'
/home/pbz/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/puma-3.12.0/lib/puma/configuration.rb:225:in `call'
/home/pbz/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/puma-3.12.0/lib/puma/server.rb:658:in `handle_request'
/home/pbz/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/puma-3.12.0/lib/puma/server.rb:472:in `process_client'
/home/pbz/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/puma-3.12.0/lib/puma/server.rb:332:in `block in run'
/home/pbz/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/puma-3.12.0/lib/puma/thread_pool.rb:133:in `block in spawn_thread'
Don't override initialize in the AR. It could possibly break a lot of stuff in your models.
You can use after_initialize.
The after_initialize callback will be called whenever an Active Record
object is instantiated, either by directly using new or when a record
is loaded from the database. It can be useful to avoid the need to
directly override your Active Record initialize method.
def after_initialize
# Gets called right after Calculation.new
# Do some stuff here
end
If you still want to use initialize you must do something like this:
def initialize(attributes = {})
super
self.attributes = attributes
end
I did find out (thanks to #Зелёный), that to create values for the model after creating it (new) I need to use the after_initialize callback Rails provides. Together with this comment on how to access model instance variables, I was able to achieve the functionality I wanted.
The original NoMethodError was a result of my incorrect use of the initialize method. The following code is the final result, which works with the default controller.
require 'digest'
class Calculation < ApplicationRecord
##known_algorithms = ['SHA2_256', 'SHA2_384', 'SHA2_512']
after_initialize :init
private
def init
validate!
calculate!
end
def calculate!
self.hash_value, self.timestamp = digest
end
def digest
case algorithm
when 'SHA2_256'
result = Digest::SHA2.hexdigest(value)
when 'SHA2_384'
result = Digest::SHA2.new(384).hexdigest(value)
when 'SHA2_512'
result = Digest::SHA2.new(512).hexdigest(value)
end
return result, DateTime.now
end
def validate!
raise ArgumentError.new('Value cannot be empty or NIL!') if value.nil? or value.empty?
raise ArgumentError.new('Unknown hashing algorithm!') unless ##known_algorithms.include? algorithm
end
end

Rails after_save send mail with updated columns

I am stuck in an issue, wherein I would like to send mail after the after_save callback in rails.
Below is my code snippet:
class Response < ActiveRecord::Base
after_create :pending_with
protected
def pending_with
self.approver = self.mapping.user
end
end
class ResponsesController < ApplicationController
def create
#response = current_user.responses.new(response_params)
respond_to do |format|
if #response.save
flash[:notice] = "Response has been saved successfully."
Notification.confirm_approver(#response).deliver
format.html { redirect_to dashboard_home_url }
else
flash[:error] = "There is some problem while saving the responses. Please try again."
format.html { render action: 'new' }
end
end
end
end
class Notification < ApplicationMailer
def confirm_approver(response)
#response = response
p "============"
p #response.approver.email.inspect
end
end
My issue is that, I am not getting approver. Getting error:
undefined method `approver' for nil:NilClass
When I checked the record in the database, apporver ('id') is successfully saved. Am I missing anything here?
BACKTRACE:
app/mailers/notification.rb:11:in `confirm_approver'
vendor/gems/ruby/1.9.1actionpack (4.1.8) lib/abstract_controller/base.rb:189:in `process_action'
vendor/gems/ruby/1.9.1actionpack (4.1.8) lib/abstract_controller/callbacks.rb:20:in `block in process_action'
vendor/gems/ruby/1.9.1activesupport (4.1.8) lib/active_support/callbacks.rb:82:in `run_callbacks'
vendor/gems/ruby/1.9.1actionpack (4.1.8) lib/abstract_controller/callbacks.rb:19:in `process_action'
vendor/gems/ruby/1.9.1actionpack (4.1.8) lib/abstract_controller/base.rb:136:in `process'
vendor/gems/ruby/1.9.1actionview (4.1.8) lib/action_view/rendering.rb:30:in `process'
vendor/gems/ruby/1.9.1actionmailer (4.1.8) lib/action_mailer/base.rb:580:in `block in process'
vendor/gems/ruby/1.9.1activesupport (4.1.8) lib/active_support/notifications.rb:159:in `block in instrument'
vendor/gems/ruby/1.9.1activesupport (4.1.8) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
vendor/gems/ruby/1.9.1activesupport (4.1.8) lib/active_support/notifications.rb:159:in `instrument'
vendor/gems/ruby/1.9.1actionmailer (4.1.8) lib/action_mailer/base.rb:577:in `process'
vendor/gems/ruby/1.9.1actionmailer (4.1.8) lib/action_mailer/base.rb:568:in `initialize'
vendor/gems/ruby/1.9.1actionmailer (4.1.8) lib/action_mailer/base.rb:551:in `new'
vendor/gems/ruby/1.9.1actionmailer (4.1.8) lib/action_mailer/base.rb:551:in `method_missing'
app/controllers/responses_controller.rb:23:in `block in create'
vendor/gems/ruby/1.9.1actionpack (4.1.8) lib/action_controller/metal/mime_responds.rb:433:in `call'
vendor/gems/ruby/1.9.1actionpack (4.1.8) lib/action_controller/metal/mime_responds.rb:433:in `retrieve_collector_from_mimes'
vendor/gems/ruby/1.9.1actionpack (4.1.8) lib/action_controller/metal/mime_responds.rb:256:in `respond_to'
app/controllers/responses_controller.rb:19:in `create'
Hi Based on #zwippie inputs, it worked. Just made little modification to it.
def create
#response = current_user.responses.new(response_params)
respond_to do |format|
if #response.save && #response.reload
Notification.confirm_approver(#response).deliver
flash[:notice] = "Response has been created successfully."
else
format.html { render action: 'new' }
end
end
end

Can't edit custom field for Users (Account update) in my Rails 4 app with Devise (Rails 4, devise 3, formtastic, geocoder)

I'm geolocating the user with geocoder and storing the value I get in the User's table (in a attribute called user_country_name).
I am sure it has nothing to do with geocoder but I don't manage to simply edit the country in User Account page.
I tried to edit the email and the passwoird and it works but not the other custom fields i added compared to Devise basic form.
I think I've done all needed to update account attributes in Rails 4 but keep getting this error for 2 whole days!
ActionController::UnpermittedParameters at /
found unpermitted parameters: user_country_name
Here is my form for User info edit
<%= semantic_form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put, :class => 'form-vertical' }) do |f| %>
<%= f.semantic_errors %>
<%= f.inputs do %>
<%= f.input :email, :required => true %>
<%= f.input :user_country_name,
:as => :select,
:collection => COUNTRIES, # sends to a constant I have with all countries
:prompt => true
%>
<%= f.input :password, :input_html => { :autocomplete => "off" }, :hint => t("devise.registrations.edit_account_page.leave_blank_if_dont_want_to_change"), :required => false %>
<%= f.input :password_confirmation, :required => false %>
<% end %>
<%= f.actions do %>
<div>
<%= f.action :submit, :label => t("devise.registrations.edit_account_page.update"), :button_html => { :class => 'btn-primary' } %>
</div>
<div class="half-right-small return-login">
<%= link_to t("directions.back"), :back %>
</div>
<% end %>
<% end %>
here is my application controller
class ApplicationController < ActionController::Base
protect_from_forgery
include CountrySetter # handle localization through ip lookup and the I18n used
include LocaleSetter
# handle Cancan authorization exception
rescue_from CanCan::AccessDenied do |exception|
exception.default_message = t("errors.application_controller_exception_messages.only_open_to_admin")
if current_user # if it's user redirect to main HP
redirect_to root_path, :alert => exception.message
else
redirect_to customerinterface_path, :alert=> exception.message
end
end
before_filter :configure_permitted_parameters, if: :devise_controller?
private
before_filter :authenticate_user_from_token!
before_filter :authenticate_customer_from_token!
def authenticate_user_from_token!
user_email = params[:user_email].presence
user = user_email && User.find_by_email(user_email)
if user && Devise.secure_compare(user.authentication_token, params[:user_token])
sign_in user, store: false # we are signing in user if it exists. sign_in is devise method to sign in any user
redirect_to root_path # now we are redirecting the user to root_path i.e our homepage
end
end
protected
def configure_permitted_parameters
[:sign_up, :account_update].each do |sanitize_me|
devise_parameter_sanitizer.for(sanitize_me) do |u|
u.permit(:email, :password, :password_confirmation, :user_country_name)
end
end
end
def devise_parameter_sanitizer
if resource_class == User
UserParameterSanitizer.new(User, :user, params)
else # for customers
CustomerParameterSanitizer.new(Customer, :customer, params)
end
end
end
and finally the RegistrationsController form Devise:
class RegistrationsController < Devise::RegistrationsController
def update
# added for upgrade to Rails 4
account_update_params = devise_parameter_sanitizer.sanitize(:account_update)
# required for settings form to submit when password is left blank
if account_update_params[:password].blank?
account_update_params.delete("password")
account_update_params.delete("password_confirmation")
end
#user = User.find(current_user.id)
if #user.update(account_update_params) # Rails 4 .update introduced with same effect as .update_attributes
set_flash_message :notice, :updated
# Sign in the user bypassing validation in case his password changed
sign_in #user, :bypass => true
redirect_to after_update_path_for(#user)
else
render "edit"
end
end
# for Rails 4 Strong Parameters
def resource_params
params.require(:user).permit(:email, :password, :password_confirmation, :current_password, :user_country_name)
end
private :resource_params
# used to update user-country by ip lookup when user signs up and associate newly signed-up user with a country
# source - stackoverflow.com/questions/24294169/devise-sign-up-how-to-save-an-attribute-without-having-a-form-field-for-it-ra
protected
def after_sign_up_path_for(resource)
resource.update(user_country_name: set_country) #use concerns/CountrySetter loaded by ApplicationController
root_path
end
end
EDIT
To answer some comments asking for the Route
MyApp::Application.routes.draw do
# redundancy with below standard users 'root to' code. Goal: to easily be able to change
# the page if decide one day that users should see a different page when they log in
# used to be a bug- solved with: https://github.com/plataformatec/devise/issues/2393#issuecomment-17544388
authenticated :user do
root to: 'static_pages#home', as: :authenticated_root
end
# Homepage for unauthenticated users
# used to be a bug- solved with: https://github.com/plataformatec/devise/issues/2393#issuecomment-17544388
unauthenticated do
root to: 'static_pages#home' # , as: :unauthenticated_root
end
# Routes for users
devise_for :users,
:token_authentication_key => 'authentication_key',
:controllers => { confirmations: 'confirmations',
registrations: 'registrations',
sessions: 'sessions',
passwords: 'passwords',
unlocks: 'unlocks' },
path: '', # inspired by Nitish solution to make devise urls custom (source: tackoverflow.com/questions/19889570/rails-devise-user-registration-route-post)
path_names: { :sign_in => "signin",
:sign_out => "logout",
:sign_up => "signup" }
resources :users
# Routes for customers
devise_for :customers,
controllers: { registrations: 'customers/registrations', # inspired by stackoverflow.com/questions/20913157/devise-views-with-multiple-models
confirmations: 'customers/confirmations',
sessions: 'customers/sessions',
passwords: 'customers/passwords',
unlocks: 'customers/unlocks' },
path: 'advertiser', # inspired by Nitish solution to make devise urls custom (source: tackoverflow.com/questions/19889570/rails-devise-user-registration-route-post)
path_names: { :sign_in => "signin",
:sign_out => "logout",
:sign_up => "signup" }
# Routes for the interface with reportings and private data for Customers
# Customers interface HP can be accessed at /campaigns
match '/customerinterface',
to: 'clientreporting_pages#index',
path: 'campaigns',
via: 'get'
# Routes for all managed by Active Admin (deals creation, prizes creation...)
devise_for :admin_users, ActiveAdmin::Devise.config
ActiveAdmin.routes(self)
# Static Pages
match '/help', to: 'static_pages#help', path: 'help', via: 'get'
match '/aboutus', to: 'static_pages#aboutus', path: 'about-us', via: 'get'
match '/contact', to: 'static_pages#contact', via: 'get'
match '/howitworks', to: 'static_pages#howitworks', path: 'about', via: 'get'
match '/globalpresence', to: 'static_pages#globalpresence',path: 'global', via: 'get'
And here is the detailed log of error I get in my local console
Started PUT "/" for 127.0.0.1 at 2014-10-08 19:55:50 +0200
Processing by RegistrationsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"geygeyegyegyegyegeykd7NwrVyAw=", "user"=>{"email"=>"emailtest#gmail.com", "user_country_name"=>"Germany", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"<span class="}
User Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = 457 ORDER BY "users"."id" ASC LIMIT 1
Completed 500 Internal Server Error in 7ms
ActionController::UnpermittedParameters - found unpermitted parameters: user_country_name:
actionpack (4.0.5) lib/action_controller/metal/strong_parameters.rb:372:in `unpermitted_parameters!'
actionpack (4.0.5) lib/action_controller/metal/strong_parameters.rb:270:in `permit'
devise (3.2.4) lib/devise/parameter_sanitizer.rb:66:in `permit'
devise (3.2.4) lib/devise/parameter_sanitizer.rb:58:in `account_update'
devise (3.2.4) lib/devise/parameter_sanitizer.rb:77:in `default_sanitize'
devise (3.2.4) lib/devise/parameter_sanitizer.rb:24:in `sanitize'
app/controllers/registrations_controller.rb:11:in `update'
actionpack (4.0.5) lib/action_controller/metal/implicit_render.rb:4:in `send_action'
actionpack (4.0.5) lib/abstract_controller/base.rb:189:in `process_action'
actionpack (4.0.5) lib/action_controller/metal/rendering.rb:10:in `process_action'
actionpack (4.0.5) lib/abstract_controller/callbacks.rb:18:in `block in process_action'
activesupport (4.0.5) lib/active_support/callbacks.rb:483:in `_run__3174996646979711185__process_action__callbacks'
activesupport (4.0.5) lib/active_support/callbacks.rb:80:in `run_callbacks'
actionpack (4.0.5) lib/abstract_controller/callbacks.rb:17:in `process_action'
actionpack (4.0.5) lib/action_controller/metal/rescue.rb:29:in `process_action'
actionpack (4.0.5) lib/action_controller/metal/instrumentation.rb:31:in `block in process_action'
activesupport (4.0.5) lib/active_support/notifications.rb:159:in `block in instrument'
activesupport (4.0.5) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
activesupport (4.0.5) lib/active_support/notifications.rb:159:in `instrument'
actionpack (4.0.5) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
actionpack (4.0.5) lib/action_controller/metal/params_wrapper.rb:250:in `process_action'
activerecord (4.0.5) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
actionpack (4.0.5) lib/abstract_controller/base.rb:136:in `process'
actionpack (4.0.5) lib/abstract_controller/rendering.rb:44:in `process'
actionpack (4.0.5) lib/action_controller/metal.rb:195:in `dispatch'
actionpack (4.0.5) lib/action_controller/metal/rack_delegation.rb:13:in `dispatch'
actionpack (4.0.5) lib/action_controller/metal.rb:231:in `block in action'
actionpack (4.0.5) lib/action_dispatch/routing/route_set.rb:80:in `call'
actionpack (4.0.5) lib/action_dispatch/routing/route_set.rb:80:in `dispatch'
actionpack (4.0.5) lib/action_dispatch/routing/route_set.rb:48:in `call'
actionpack (4.0.5) lib/action_dispatch/routing/mapper.rb:44:in `call'
actionpack (4.0.5) lib/action_dispatch/journey/router.rb:71:in `block in call'
actionpack (4.0.5) lib/action_dispatch/journey/router.rb:59:in `each'
actionpack (4.0.5) lib/action_dispatch/journey/router.rb:59:in `call'
actionpack (4.0.5) lib/action_dispatch/routing/route_set.rb:674:in `call'
warden (1.2.3) lib/warden/manager.rb:35:in `block in call'
warden (1.2.3) lib/warden/manager.rb:34:in `catch'
warden (1.2.3) lib/warden/manager.rb:34:in `call'
rack (1.5.2) lib/rack/etag.rb:23:in `call'
rack (1.5.2) lib/rack/conditionalget.rb:35:in `call'
rack (1.5.2) lib/rack/head.rb:11:in `call'
actionpack (4.0.5) lib/action_dispatch/middleware/params_parser.rb:27:in `call'
actionpack (4.0.5) lib/action_dispatch/middleware/flash.rb:241:in `call'
rack (1.5.2) lib/rack/session/abstract/id.rb:225:in `context'
rack (1.5.2) lib/rack/session/abstract/id.rb:220:in `call'
actionpack (4.0.5) lib/action_dispatch/middleware/cookies.rb:486:in `call'
activerecord (4.0.5) lib/active_record/query_cache.rb:36:in `call'
activerecord (4.0.5) lib/active_record/connection_adapters/abstract/connection_pool.rb:626:in `call'
activerecord (4.0.5) lib/active_record/migration.rb:373:in `call'
actionpack (4.0.5) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
activesupport (4.0.5) lib/active_support/callbacks.rb:373:in `_run__2636980444171422651__call__callbacks'
activesupport (4.0.5) lib/active_support/callbacks.rb:80:in `run_callbacks'
actionpack (4.0.5) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
actionpack (4.0.5) lib/action_dispatch/middleware/reloader.rb:64:in `call'
actionpack (4.0.5) lib/action_dispatch/middleware/remote_ip.rb:76:in `call'
better_errors (1.1.0) lib/better_errors/middleware.rb:84:in `protected_app_call'
better_errors (1.1.0) lib/better_errors/middleware.rb:79:in `better_errors_call'
better_errors (1.1.0) lib/better_errors/middleware.rb:56:in `call'
actionpack (4.0.5) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call'
actionpack (4.0.5) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
railties (4.0.5) lib/rails/rack/logger.rb:38:in `call_app'
railties (4.0.5) lib/rails/rack/logger.rb:20:in `block in call'
activesupport (4.0.5) lib/active_support/tagged_logging.rb:68:in `block in tagged'
activesupport (4.0.5) lib/active_support/tagged_logging.rb:26:in `tagged'
activesupport (4.0.5) lib/active_support/tagged_logging.rb:68:in `tagged'
railties (4.0.5) lib/rails/rack/logger.rb:20:in `call'
quiet_assets (1.0.2) lib/quiet_assets.rb:18:in `call_with_quiet_assets'
actionpack (4.0.5) lib/action_dispatch/middleware/request_id.rb:21:in `call'
rack (1.5.2) lib/rack/methodoverride.rb:21:in `call'
rack (1.5.2) lib/rack/runtime.rb:17:in `call'
activesupport (4.0.5) lib/active_support/cache/strategy/local_cache.rb:83:in `call'
rack (1.5.2) lib/rack/lock.rb:17:in `call'
rack (1.5.2) lib/rack/sendfile.rb:112:in `call'
railties (4.0.5) lib/rails/engine.rb:511:in `call'
railties (4.0.5) lib/rails/application.rb:97:in `call'
rack (1.5.2) lib/rack/lock.rb:17:in `call'
rack (1.5.2) lib/rack/content_length.rb:14:in `call'
rack (1.5.2) lib/rack/handler/webrick.rb:60:in `service'
/home/me/.rvm/rubies/ruby-2.0.0-p451/lib/ruby/2.0.0/webrick/httpserver.rb:138:in `service'
/home/me/.rvm/rubies/ruby-2.0.0-p451/lib/ruby/2.0.0/webrick/httpserver.rb:94:in `run'
/home/me/.rvm/rubies/ruby-2.0.0-p451/lib/ruby/2.0.0/webrick/server.rb:295:in `block in start_thread'
EDIT #2
I tried everything that you guys proposed but nothing worked. then i tried one thing: I removed devise_parameter_sanitizer. then it works!! but should/can i remove this without compromising the security of the app? isn't this block important?
Here is the block I removed:
def devise_parameter_sanitizer
if resource_class == User
UserParameterSanitizer.new(User, :user, params)
else # for customers
CustomerParameterSanitizer.new(Customer, :customer, params)
end
end
What does it tell me about the problem ? maybe it's an important clue to the real bug but i don't get it:)
Many thanks for any help!
can you try this please
application controller
before_action :configure_permitted_parameters, if: :devise_controller?
and
application Controller
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) << [your params]
devise_parameter_sanitizer.for(:account_update) << [your params]
end
Registrations controller
<!-- REMOVE -->
# added for upgrade to Rails 4
account_update_params = devise_parameter_sanitizer.sanitize(:account_update)
# for Rails 4 Strong Parameters
def resource_params
params.require(:user).permit(:email, :password, :password_confirmation, :current_password, :user_country_name)
end
private :resource_params
let me know how this works out for you, you seem to be declaring your permitted params too many times in different places
My solution for this was to :
Create a true rest controllers/users_controller and to use Devise controllers just for controllers/users/registration_controllerand controllers/users/sessions_controller.
Unset devise control of create/edit un routes.rb
devise_for :users, controllers: { registrations: "users/registrations",
sessions: "users/sessions" }
resources :users
Answer Update
In Rails 4 you must permit all parameters with params.permit(params_list_to_allow) or for rapid upgrade from Rails 3 params.permit! to pass mass assignment
Like this you have a normal controller for manage your User model likes other application controllers.
in controller/users_controller.rb
def update
#user = User.find(params[:id])
respond_to do |format|
if #user.update_attributes(user_params)
format.html { redirect_to #user, notice: 'User was successfully created.' }
else
format.html { redirect_to #user, notice: 'Errors.' }
end
end
end
private
def user_params
params.permit!
end

Routing problems one-to-one association

I tried to route as following with my 2 models pimp and mepager (one-to-one relation):
/config/routes.rb
root :to => 'pimps#index'
get '/:pimp_id/mepager', :to => 'mepager#show', :as => 'mepager'
My mepager show action looks like this:
/app/controllers/mepagers_controller.rb
before_action :set_pimp
def show
#mepager = #pimp.mepager
end
private
def set_pimp
#pimp = Pimp.find(params[:pimp_id])
end
Now I tested in the rails console the function Pimp.first.mepager what should be equal to #pimp.mepager and it gives me the right mepager object back with all atttributes. But if I try to open '/:pimp_id/mepager' in my webapplication (with an existing pimp that has a mepager linked to it) I get following error
Routing Error
uninitialized constant MepagerController
Did I miss something?
Regards.
Complete error msg:
Started GET "/1/mepager" for 127.0.0.1 at 2014-06-06 08:55:20 +0200
ActionController::RoutingError (uninitialized constant
MepagerController): activesupport (4.0.0)
lib/active_support/inflector/methods.rb:226:in const_get'
activesupport (4.0.0) lib/active_support/inflector/methods.rb:226:in
block in constantize' activesupport (4.0.0)
lib/active_support/inflector/methods.rb:224:in each' activesupport
(4.0.0) lib/active_support/inflector/methods.rb:224:ininject'
activesupport (4.0.0) lib/active_support/inflector/methods.rb:224:in
constantize' actionpack (4.0.0)
lib/action_dispatch/routing/route_set.rb:76:incontroller_reference'
actionpack (4.0.0) lib/action_dispatch/routing/route_set.rb:66:in
controller' actionpack (4.0.0)
lib/action_dispatch/routing/route_set.rb:44:incall' actionpack
(4.0.0) lib/action_dispatch/journey/router.rb:71:in block in call'
actionpack (4.0.0) lib/action_dispatch/journey/router.rb:59:ineach'
actionpack (4.0.0) lib/action_dispatch/journey/router.rb:59:in call'
actionpack (4.0.0) lib/action_dispatch/routing/route_set.rb:655:in
call' rack (1.5.2) lib/rack/etag.rb:23:in call' rack (1.5.2)
lib/rack/conditionalget.rb:25:incall' rack (1.5.2)
lib/rack/head.rb:11:in call' actionpack (4.0.0)
lib/action_dispatch/middleware/params_parser.rb:27:incall'
actionpack (4.0.0) lib/action_dispatch/middleware/flash.rb:241:in
call' rack (1.5.2) lib/rack/session/abstract/id.rb:225:incontext'
rack (1.5.2) lib/rack/session/abstract/id.rb:220:in call'
actionpack (4.0.0) lib/action_dispatch/middleware/cookies.rb:486:in
call' activerecord (4.0.0) lib/active_record/query_cache.rb:36:in
call' activerecord (4.0.0)
lib/active_record/connection_adapters/abstract/connection_pool.rb:626:in
cal l' activerecord (4.0.0) lib/active_record/migration.rb:369:in
call' actionpack (4.0.0)
lib/action_dispatch/middleware/callbacks.rb:29:inblock in call'
activesupport (4.0.0) lib/active_support/callbacks.rb:373:in
_run__226962734__call__callbacks' activesupport (4.0.0)
lib/active_support/callbacks.rb:80:inrun_callbacks' actionpack
(4.0.0) lib/action_dispatch/middleware/callbacks.rb:27:in call'
actionpack (4.0.0) lib/action_dispatch/middleware/reloader.rb:64:in
call' actionpack (4.0.0)
lib/action_dispatch/middleware/remote_ip.rb:76:in call' actionpack
(4.0.0) lib/action_dispatch/middleware/debug_exceptions.rb:17:in
call' actionpack (4.0.0)
lib/action_dispatch/middleware/show_exceptions.rb:30:in call'
railties (4.0.0) lib/rails/rack/logger.rb:38:incall_app' railties
(4.0.0) lib/rails/rack/logger.rb:21:in block in call' activesupport
(4.0.0) lib/active_support/tagged_logging.rb:67:inblock in tagged'
activesupport (4.0.0) lib/active_support/tagged_logging.rb:25:in
tagged' activesupport (4.0.0)
lib/active_support/tagged_logging.rb:67:intagged' railties (4.0.0)
lib/rails/rack/logger.rb:21:in call' actionpack (4.0.0)
lib/action_dispatch/middleware/request_id.rb:21:incall' rack
(1.5.2) lib/rack/methodoverride.rb:21:in call' rack (1.5.2)
lib/rack/runtime.rb:17:incall' activesupport (4.0.0)
lib/active_support/cache/strategy/local_cache.rb:83:in call' rack
(1.5.2) lib/rack/lock.rb:17:incall' actionpack (4.0.0)
lib/action_dispatch/middleware/static.rb:64:in call' railties
(4.0.0) lib/rails/engine.rb:511:incall' railties (4.0.0)
lib/rails/application.rb:97:in call' rack (1.5.2)
lib/rack/lock.rb:17:incall' rack (1.5.2)
lib/rack/content_length.rb:14:in call' rack (1.5.2)
lib/rack/handler/webrick.rb:60:inservice'
C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/webrick/httpserver.rb:138:in
service'
C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/webrick/httpserver.rb:94:in
run'
C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/webrick/server.rb:191:in
`block in start_thread'
Rendered
C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/actionpack-4.0.0/lib/action_dispatch
/middleware/templates/rescues/_trace.erb (1.0ms) Rendered
C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/actionpack-4.0.0/lib/action_dispatch
/middleware/templates/routes/_route.html.erb (1.0ms) Rendered
C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/actionpack-4.0.0/lib/action_dispatch
/middleware/templates/routes/_table.html.erb (1.0ms) Rendered
C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/actionpack-4.0.0/lib/action_dispatch
/middleware/templates/rescues/routing_error.erb within rescues/layout
(42.0ms)
Console test
> irb(main):001:0> Pimp.first.mepager ←[1m←[36mSQL (0.0ms)←[0m
> ←[1mUSE [rails_confreport_develop]←[0m ←[1m←[35mPimp Load
> (1.0ms)←[0m EXEC sp_executesql N'SELECT TOP (1) [pimps].* Y
> [pimps].[id] ASC' ←[1m←[36mMepager Load (1.0ms)←[0m ←[1mEXEC
> sp_executesql N'SELECT TOP (1) [me gers] WHERE [mepagers].[pimp_id] =
> #0 ORDER BY [mepagers].[id] ASC', N'#0 int', id", 2]]
> => #<Mepager id: 2, pimp_id: 2, pre: "geqgewqrgq", post: "egewqewqgewqgewq", com .0, save_c: nil, save_other: "", save_otherv:
> nil, affect_design: "", affect_str "", affect_other: "", affect_dno:
> "", affect_mid: "", affect_otherdoc: "", owner ence: "", created_at:
> "2014-06-06 06:36:44", updated_at: "2014-06-06 06:36:44">
mepagers_controller.rb
class MepagersController < ApplicationController
before_action :set_mepager, only: [:show, :edit, :update, :destroy]
before_action :set_pimp
# GET /mepagers
# GET /mepagers.json
#def index
##mepagers = Mepager.all
#end
# GET /mepagers/1
# GET /mepagers/1.json
def show
#mepager = #pimp.mepager
end
# GET /mepagers/new
def new
#mepager = #pimp.build_mepager
end
# GET /mepagers/1/edit
def edit
#mepager = #pimp.mepager
end
# POST /mepagers
# POST /mepagers.json
def create
#mepager = #pimp.build_mepager(mepager_params)
respond_to do |format|
if #mepager.save
format.html { redirect_to [#pimp,#mepager], notice: 'Mepager was successfully created.' }
format.json { render action: 'show', status: :created, location: #mepager }
else
format.html { render action: 'new' }
format.json { render json: #mepager.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /mepagers/1
# PATCH/PUT /mepagers/1.json
def update
#mepager = #pimp.mepager
respond_to do |format|
if #mepager.update(mepager_params)
format.html { redirect_to [#pimp,#mepager], notice: 'Mepager was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #mepager.errors, status: :unprocessable_entity }
end
end
end
# DELETE /mepagers/1
# DELETE /mepagers/1.json
def destroy
#mepager = #pimp.mepager
#mepager.destroy
respond_to do |format|
format.html { redirect_to mepagers_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_mepager
#mepager = Mepager.find(params[:id])
end
def set_pimp
#pimp = Pimp.find(params[:pimp_id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def mepager_params
params.require(:mepager).permit(:pimp_id, :pre, :post, :comment, :save_h, :save_c, :save_other, :save_otherv, :affect_design, :affect_stress, :affect_me, :affect_other, :affect_dno, :affect_mid, :affect_otherdoc, :owner, :pps, :reference)
end
end
You have written get '/:pimp_id/mepager', :to => 'mepager#show', :as => 'mepager' but it should be get '/:pimp_id/mepager', :to => 'mepagers#show', :as => 'mepager'. You forgot to add "s" in your "mepages#show". For more information refer to here.
One more thing since your mepager is nested inside pimp you don't need your :set_mepager filter. You can either remove it or do something like this inside your mepagers_controller.rb
class MepagersController < ApplicationController
before_action :set_pimp
before_action :set_mepager, only: [:show, :edit, :update, :destroy]
# your actions
private
# Use callbacks to share common setup or constraints between actions.
def set_mepager
#mepager = #pimp.mepager
end
def set_pimp
#pimp = Pimp.find(params[:pimp_id])
end
end
You need to modify your routes this way:
root :to => 'pimps#index'
get '/:pimp_id/mepager', :to => 'mepagers#show', :as => 'mepager'
Rails infers the controller name from the :to keyword. The notation mepagers#show means the show method of MepagersController
Source: http://edgeguides.rubyonrails.org/routing.html#connecting-urls-to-code

Why does update_attributes break my Rails app?

Original Question
I'm running Rails 3.0.1 on Ruby 1.9.2. Here are the relevant model, controller, and view.
Code
user.rb:
class User < ActiveRecord::Base
belongs_to :directory
attr_accessor :new_password, :new_password_confirmation
validates_confirmation_of :new_password, :if => :password_changed?
before_save :hash_password, :if => :password_changed?
def self.authenticate(login, password)
# Check to see if the user exists
if user = find_by_login(login)
# If this is an directory user, authenticate them against their directory
if user.directory
return directory_auth user, password
# Otherwise, authenticate them against the local database
elsif user.hash == Digest::SHA2.hexdigest(user.salt + password)
return user
end
end
return nil
end
def password_changed?
!#new_password.blank?
end
private
def hash_password
self.salt = ActiveSupport::SecureRandom.base64 8
self.hash = Digest::SHA2.hexdigest(self.salt + #new_password)
end
def self.directory_auth(user, password)
directory = user.directory
directory.bind['%s'] = user.login
ldap = Net::LDAP.new
if directory.use_simple_tls?
ldap.encryption :simple_tls
end
ldap.host = directory.host
ldap.port = directory.port
ldap.auth directory.bind, password
return user if ldap.bind
return nil
end
end
users_controller.rb:
class UsersController < ApplicationController
def index
#users = User.all
end
def show
#user = User.find params[:id]
end
def new
#user = User.new
end
def create
#user = User.new params[:user]
if #user.save
flash[:notice] = "#{#user.login} was created"
redirect_to #user
else
flash[:notice] = 'The user could not be created'
render :action => 'new'
end
end
def edit
#user = User.find params[:id]
end
def update
#user = User.find params[:id]
#user.attributes = params[:user] # this works
# #user.update_attributes params[:user] # this does NOT work
if #user.save # I realize this is redundant if update_attributes is working
flash[:notice] = "#{#user.login} was updated"
redirect_to #user
else
flash[:notice] = 'The user could not be updated'
render :action => 'edit'
end
end
def destroy
#user = User.find params[:id]
#user.destroy
flash[:notice] = "#{#user.login} was deleted"
redirect_to users_url
end
end
users.html.erb:
<%= form_for #user do |f| %>
<%= f.label :login %>:
<%= f.text_field :login %>
<br>
<%= f.label :new_password %>:
<%= f.password_field :new_password %>
<br>
<%= f.label :new_password_confirmation %>:
<%= f.password_field :new_password_confirmation %>
<br>
<% if directories = Directory.all.empty? %>
No directories defined. You can <%= link_to 'add a directory', new_directory_path %>.
<% else %>
<%= f.label :directory_id %>:
<%= f.collection_select :directory_id, Directory.all, :id, :name, { :include_blank => 'None' } %>
<% end %>
<br>
<%= f.label :admin, 'Administrator?' %>:
<%= f.check_box :admin %>
<br>
<%= f.submit %>
<% end %>
schema.rb:
ActiveRecord::Schema.define(:version => 20101107005603) do
create_table "directories", :force => true do |t|
t.string "host"
t.string "bind"
t.boolean "use_simple_tls"
t.integer "port"
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "users", :force => true do |t|
t.string "login"
t.string "hash"
t.string "salt"
t.boolean "admin"
t.integer "directory_id"
t.datetime "created_at"
t.datetime "updated_at"
end
end
I have another model/controller/view for directories that is very similar, but doesn't have virtual accessors or other model ids, and update_attributes works fine in it. I did a quick test app with rails g scaffold users name:string password:string and all CRUD actions work fine.
This was driving me nuts! I found a workaround, but I really want to understand why update_attributes doesn't work here. When I run the update action, I get this:
TypeError in UsersController#update
can't convert nil into Integer
Rails.root: /home/force/proj
app/controllers/users_controller.rb:34:in `update'
Full Stack Trace
activerecord (3.0.1) lib/active_record/connection_adapters/abstract/database_statements.rb:318:in `uniq'
activerecord (3.0.1) lib/active_record/connection_adapters/abstract/database_statements.rb:318:in `commit_transaction_records'
activerecord (3.0.1) lib/active_record/connection_adapters/abstract/database_statements.rb:165:in `transaction'
activerecord (3.0.1) lib/active_record/transactions.rb:204:in `transaction'
activerecord (3.0.1) lib/active_record/transactions.rb:287:in `with_transaction_returning_status'
activerecord (3.0.1) lib/active_record/persistence.rb:126:in `update_attributes'
app/controllers/users_controller.rb:34:in `update'
actionpack (3.0.1) lib/action_controller/metal/implicit_render.rb:4:in `send_action'
actionpack (3.0.1) lib/abstract_controller/base.rb:150:in `process_action'
actionpack (3.0.1) lib/action_controller/metal/rendering.rb:11:in `process_action'
actionpack (3.0.1) lib/abstract_controller/callbacks.rb:18:in `block in process_action'
activesupport (3.0.1) lib/active_support/callbacks.rb:435:in `_run__805567340__process_action__482539529__callbacks'
activesupport (3.0.1) lib/active_support/callbacks.rb:409:in `_run_process_action_callbacks'
activesupport (3.0.1) lib/active_support/callbacks.rb:93:in `run_callbacks'
actionpack (3.0.1) lib/abstract_controller/callbacks.rb:17:in `process_action'
actionpack (3.0.1) lib/action_controller/metal/instrumentation.rb:30:in `block in process_action'
activesupport (3.0.1) lib/active_support/notifications.rb:52:in `block in instrument'
activesupport (3.0.1) lib/active_support/notifications/instrumenter.rb:21:in `instrument'
activesupport (3.0.1) lib/active_support/notifications.rb:52:in `instrument'
actionpack (3.0.1) lib/action_controller/metal/instrumentation.rb:29:in `process_action'
actionpack (3.0.1) lib/action_controller/metal/rescue.rb:17:in `process_action'
actionpack (3.0.1) lib/abstract_controller/base.rb:119:in `process'
actionpack (3.0.1) lib/abstract_controller/rendering.rb:40:in `process'
actionpack (3.0.1) lib/action_controller/metal.rb:133:in `dispatch'
actionpack (3.0.1) lib/action_controller/metal/rack_delegation.rb:14:in `dispatch'
actionpack (3.0.1) lib/action_controller/metal.rb:173:in `block in action'
actionpack (3.0.1) lib/action_dispatch/routing/route_set.rb:62:in `call'
actionpack (3.0.1) lib/action_dispatch/routing/route_set.rb:62:in `dispatch'
actionpack (3.0.1) lib/action_dispatch/routing/route_set.rb:27:in `call'
rack-mount (0.6.13) lib/rack/mount/route_set.rb:148:in `block in call'
rack-mount (0.6.13) lib/rack/mount/code_generation.rb:93:in `block in recognize'
rack-mount (0.6.13) lib/rack/mount/code_generation.rb:103:in `optimized_each'
rack-mount (0.6.13) lib/rack/mount/code_generation.rb:92:in `recognize'
rack-mount (0.6.13) lib/rack/mount/route_set.rb:139:in `call'
actionpack (3.0.1) lib/action_dispatch/routing/route_set.rb:492:in `call'
actionpack (3.0.1) lib/action_dispatch/middleware/best_standards_support.rb:17:in `call'
actionpack (3.0.1) lib/action_dispatch/middleware/head.rb:14:in `call'
rack (1.2.1) lib/rack/methodoverride.rb:24:in `call'
actionpack (3.0.1) lib/action_dispatch/middleware/params_parser.rb:21:in `call'
actionpack (3.0.1) lib/action_dispatch/middleware/flash.rb:182:in `call'
actionpack (3.0.1) lib/action_dispatch/middleware/session/abstract_store.rb:149:in `call'
actionpack (3.0.1) lib/action_dispatch/middleware/cookies.rb:287:in `call'
activerecord (3.0.1) lib/active_record/query_cache.rb:32:in `block in call'
activerecord (3.0.1) lib/active_record/connection_adapters/abstract/query_cache.rb:28:in `cache'
activerecord (3.0.1) lib/active_record/query_cache.rb:12:in `cache'
activerecord (3.0.1) lib/active_record/query_cache.rb:31:in `call'
activerecord (3.0.1) lib/active_record/connection_adapters/abstract/connection_pool.rb:355:in `call'
actionpack (3.0.1) lib/action_dispatch/middleware/callbacks.rb:46:in `block in call'
activesupport (3.0.1) lib/active_support/callbacks.rb:415:in `_run_call_callbacks'
actionpack (3.0.1) lib/action_dispatch/middleware/callbacks.rb:44:in `call'
rack (1.2.1) lib/rack/sendfile.rb:107:in `call'
actionpack (3.0.1) lib/action_dispatch/middleware/remote_ip.rb:48:in `call'
actionpack (3.0.1) lib/action_dispatch/middleware/show_exceptions.rb:46:in `call'
railties (3.0.1) lib/rails/rack/logger.rb:13:in `call'
rack (1.2.1) lib/rack/runtime.rb:17:in `call'
activesupport (3.0.1) lib/active_support/cache/strategy/local_cache.rb:72:in `call'
rack (1.2.1) lib/rack/lock.rb:11:in `block in call'
:10:in `synchronize'
rack (1.2.1) lib/rack/lock.rb:11:in `call'
actionpack (3.0.1) lib/action_dispatch/middleware/static.rb:30:in `call'
railties (3.0.1) lib/rails/application.rb:168:in `call'
railties (3.0.1) lib/rails/application.rb:77:in `method_missing'
railties (3.0.1) lib/rails/rack/log_tailer.rb:14:in `call'
rack (1.2.1) lib/rack/content_length.rb:13:in `call'
rack (1.2.1) lib/rack/handler/webrick.rb:52:in `service'
/home/force/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/webrick/httpserver.rb:111:in `service'
/home/force/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/webrick/httpserver.rb:70:in `run'
/home/force/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/webrick/server.rb:183:in `block in start_thread'
Request Parameters
{"utf8"=>"✓",
"_method"=>"put",
"authenticity_token"=>"OvMUeM9hqfPASC0NS+Th07GELu6B+dQCCTtm3gWdJE4=",
"user"=>{"login"=>"local",
"new_password"=>"[FILTERED]",
"new_password_confirmation"=>"[FILTERED]",
"directory_id"=>"",
"admin"=>"0"},
"commit"=>"Update User",
"id"=>"13"}
Full Source Code
If you'd like to give it a try, you can download the full source at http://github.com/sidewaysmilk/deezy and edit app/controllers/users_controller.rb to use #user.update_attributes params[:user] in the update action.
OK. I feel really stupid. I'm surprised nobody caught this.
In my model, I name one of my attributes. hash, so to access it, I would say #user.hash.
ActiveRecord::Base#hash is already defined!
So I screwed up. When ActiveRecord was attempting to execute the transaction, it was trying to set a value like
#user.hash = password_hash
ActiveRecord::Base#hash= expects an integer, and password_hash outputs a String if the password is changed, and nil otherwise.
So never name a column hash! Check the documentation when you're picking column names to avoid collisions.
It looks like what may be the problem is that the user id is a primary key and somehow that is being attempted to be updated. What is the error message you get if you use the 'bangversion ofupdate_attributes:update_attributes!` ?
Without a full stack trace it's hard to say, but the error message "can't convert nil into Integer" is your key thing to track down. Likewise we want see the logs for a request that's failing. I think the Parameters: line of the log might shed light on the issue.
Update Below:
Can you pass the same params successfully to #user.update_attributes in the rails console?
rails console
user = User.find(42) # whatever a good test user's id is
user_params = {"login"=>"local", "new_password"=>"supersecret", "new_password_confirmation"=>"supersecret", "directory_id"=>"", "admin"=>"0"}
user.update_attributes!(user_params)
Does that behave any differently?

Resources