Rails 4 - sending devise params to a User model method - ruby-on-rails

i have my own RegistrationsController, which inherits from Devise. In update I want to send params to my User method like above:
def update
params = resource.delete_invoice(params) if resource.check_invoice(params[:user])
if params[:user][:name].blank?
flash[:alert] = t 'devise.registrations.wrong_user_name'
redirect_to action: 'edit' and return
end
super
end
Unfortunatelly i get error:
NoMethodError in Users::RegistrationsController#update, undefined method `[]' for nil:NilClass
It's strange because I can normally write puts params and it's not empty. How can I resolve this?

Try this:
unless params[:user].blank?
if params[:user][:name].blank?
#do your stuff
end
end

The error here is that it is trying to call [] on a nil object, as it is very unlikely that params or flash is nil, the only other place you call [] is on params[:user] which suggests that this is nil.
Couple of options, check if params[:user] is nil or use try:
if params[:user].nil? or params[:user][:name].blank?
flash[:alert] = t 'devise.registrations.wrong_user_name'
redirect_to action: 'edit' and return
end
Alternatively:
if params[:user].try(:fetch, :name).try(:blank?)
flash[:alert] = t 'devise.registrations.wrong_user_name'
redirect_to action: 'edit' and return
end
Which I think is neater. NB try is a rails method, not ruby.

Are you sure the resource is built when you run update? In Rails 4 the build_resource is being built inside that method devise/registrations_controller. Probably you want to use resource_class?

Related

Params is nil on entry into controller method

Rails 5.2
In my inventories_controller.rb, I have the following:
before_action :fetch_product, only: [:show]
def show
........
end
def fetch_product
if params.has_key?(:sku)
#product = Product.get_product(params)
end
end
This works fine, when I do: http://0.0.0.0:3000/sku/12345678
I am trying to implement search functionality, so I modified nventories_controller.rb as follows:
def fetch_product
if params.has_key?(:search) && !params[:search].blank?
product = Product.find_by_sku(params[:search])
if !product
params = params.except[:search]
redirect_to product_show_path, alert: 'Product was not found'
end
params = params.merge!(:sku, product.sku)
end
if params.has_key?(:sku)
#product = Product.get_product(params)
end
end
When I do: http://0.0.0.0:3000/sku/12345678
I get an instant error message:
undefined method `has_key?' for nil:NilClass
Using my debugger, I find that on entry into the fetch_product method, params is nil
Any idea what's going on?
params = params.merge!(:sku, product.sku) modifies the hash in place and returns nil, don't do that assignment, just call params.merge! (if you still want to do the assignment, remove the "!").
Personally, I wouldn't modify the params hash unless it's really really needed, I would use another variable.

ruby on Rails-login page

I tried to create a simple login_app using 'Authlogic' gem and i got this error:
NameError in UsersController#create
undefined local variable or method `users' for #<UsersController:0x0000000354ba48>
Extracted source (around line #28):
code:
def create
#user = User.new(params users ) # <- this line
respond_to do |format|
if #user.save
Rails.root: /home/ameex/projects/login_app
Application Trace | Framework Trace | Full Trace
app/controllers/users_controller.rb:28:in `create'
please help me to resolve this
If you are using Rails4,this should work.
class UsersController < ApplicationController
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to #user, notice: 'User was successfully created.' }
else
format.html { render action: "new" }
end
end
end
private
def user_params
params.require(:user).permit(:your_user_attr1,:your_user_attr2,..)
end
end
Have a look at Strong Parameters in these Guides.
To back up Pavan's answer, the error you had was this:
UsersController#create undefined local variable or method `users' for
#
This is a typical problem, and basically means you've referenced a local object which doesn't exist (in your case users). The issue is that now you're trying to call this, Rails cannot find it, leading to the exception
--
Params
As Pavan pointed out, the problem you have is you're calling:
#user = User.create(params users)
The problem here is you're calling a non-existent object, as explained; but what is much more important is your actual syntax is wrong. You're getting confused with two variables inside Rails:
params hash
strong_params method
When you create a new object in Rails 4, you need to tell ActiveRecord which params values you wish to populate the new record with. This is currently done by using strong_params, which essentially whitelists different members of the params hash
The bottom line is when you reference data / objects in Rails, you have to have them available beforehand. Your referencing of params users references neither the relevant params[:key][:value], nor your strong_params method
Hopefully this gives you some more ideas

Undefined method `update' for nil:NilClass even though it is not null

I have such a controller action:
def update_grade
#id = params[:id]
#grade = "Grade#{#id}".classify.constantize.find_by_id(params[:grade_id])
# render :text => #grade.grade1.inspect
respond_to do |format|
if #grade.update(:grade1 => 2)
format.html { redirect_to update_grade_homework_path, notice: 'Homework was successfully updated.' }
end
end
end
I am getting "Undefined method `update'" error but #grade is perfectly fine object. I verified it by inspecting it. What am I doing wrong?
ActiveRecord::Base doesn't have an instance method called update. (Well, actually, it does, but it's a private method so you shouldn't be able to call it using #grade.update). You may be looking for update_attributes.
#grade.update_attributes(:grade1 => 2)
(Note that if you're using Rails 3 you'll need to add the line attr_accessible :grade1 to your model or the above code will throw a MassAssignmentSecurityError.)
ActiveRecord does have a class method called update, which you can find in the docs here.
The difference in usage should be clear from this example (say you have a model Grade and you want to set the attribute "foo" to "bar" for the Grade with id 5):
# Using the class method "update":
Grade.update(5, foo: "bar")
# Using the instance method "update_attributes"
#grade = Grade.find_by(id: 5) # Or just Grade.find(5)
#grade.update_attributes(foo: "bar")
That being said, if the error message really does say "Undefined method `update' for nil:NilClass" and #grade really doesn't equal nil, then that is a bizarre error and I can't think of any reason why it might be occurring. Try changing update to update_attributes and let me know if that works.

Handling an ActiveRecord error if database is empty

I'm working on a rails 4 app, and i have the following controller code
def index
#issue = Issue.find(1)
#sections = #issue.sections
#articles = #issue.articles
end
which breaks if the database is empty with the error: "Couldn't find Issue with id=1". What is the proper way to check for this in a way that if nothing is in the db it doesn't raise an error?
One method you can use is the exists? active record method, like so:
#issue = Issue.where(id: 1)
if #issue.exists?
# do something if it exists
else
# do something if it is missing
end
Side note: Since you're attempting to find by id, you don't necessarily need the .where portion; you can simply do: Issue.exists?(1).
exists? documentation on APIDoc
In most cases such exception is expected and recommenced. For example, you can rescue it with a custom 404 page.
Anyway, if you really don't want that, you can use find_by method which will output nil if nothing found
#issue = Issue.find_by(id: 1)
you can handle that exception in your controller
rescue_from ActiveRecord::RecordNotFound, :with => :record_not_found
def record_not_found
flash[:alert] = "invalid information"
redirect_to root_url
end
or you can use a where clause
#issue = Issue.where(id: 1).first
now check for nil by
#issue.nil?

Getting "undefined method for Nil Class" error when calling the reciprocal model method

I currently have two models School and Course where School has_many courses, and Course belongs_to school. Additionally, School and Course are nested resources, where School is the parent resource, and Course the child.
I have created several test records in the Rails Console so that a query such as when the child calls upon the parent Course.first.school successfully executes and returns all the relevant information of the school Course.first is associated with.
However, when put into a controller function, I would instead get an error "undefined method `school' for nil:NilClass" for the following line:
redirect_to school_course_path(#course.school, #course)
.. as if the .school part wasn't recognized (where as it was in the console). Why is this the case, and how do I get past this error? Thanks!
Edit - as suggested, it could be that my #course instance variable isn't passed from method to method in the controller. I have attempted at passing them through via a private method, but its still giving me the same error. Here is my code (background: the model Question belongs_to Course, with Course having many questions. Course isn't part of the nested routes)
class QuestionsController < ApplicationController
def new
#course = Course.find(params[:course]) #confirmed working
self.current_course = #course #I attempt to set current_course, a private method
#question = Question.new
end
def create
#question = Question.new(params[:question]) #also works, in rails console all the questions confirms to have rails id
if #question.save
redirect_to school_course_path(current_course.school, current_course) #source of my frustrations - continues to returns same error message
else
render 'new'
end
end
private
def current_course=(course)
#current_school = course
end
def current_course
#current_course
end
end
Should work if your relationships are set up the way I think they are:
def create
#question = Question.new(params[:question])
#course = #question.course
if #question.save
redirect_to school_course_path(#course.school, #course)
else
render 'new'
end
end
Make sure you have something like this in your create action:
#course = Course.new(params[:course])
your code is okay, it seems there is problem in your redirect.. redirect it to root_path and check whether it is working??

Resources