undefined method `numbers' for nil:NilClass - ruby-on-rails

Building a simple phone book app and have a concern regarding the following:
Each of my listed contacts has a number resource, and their relationship is defined in the routes file as follows:
config/routes.rb
resources :contacts do
resources :numbers
end
In my webapp thus far, I have it so that a user can create a contact and then create a number corresponding with that contact. I list the numbers for the contact, and when the user clicks on it (in order to route to the numbers#show page for that specific number, I get the following error:
NoMethodError in NumbersController#show
undefined method `numbers' for nil:NilClass
I've had this error a ton of times, and always it happened because the contact wasn't instantiated properly. But in my code, everything is being saved to db properly as per my rails console exploration. Below is the code throwing the error, found inside my numbers controller:
def set_number #to do item
#number = #contact.numbers.find(params[:id])
end
And the parameters being passed in, according to the error page, are the following:
Parameters:
{"contact_id"=>"1",
"id"=>"1"}
I set #contact via this method in the numbers controller:
def set_contact
#contact = Contact.find(params[:contact_id])
end
and I call it at the top as so:
before_action :set_contact
Given that there are parameters, and Rails console tells me both the contact and the number were saved properly, any idea what's wrong?

As I posted as a comment:
You have to have your before_action :set_contact before your before_action :set_number, otherwise you won't have the #contact when calling the :set_number.
All the before_action runs in the order that you added them :)
Cheers

Clearly the error seems to be in set_number method inside your controller. And the reason is #contact is nil.
So, as in above comments, your set_contact method may be running after set_number

Related

Dot causing error in rails

I have a routes like this :
get ':user_name', to: 'profile#show', as: :profile
And the show method looks like this
before_action :set_user
def show
#posts = #user.posts.order('created_at DESC')
end
def set_user
#user = User.find_by(user_name: params[:user_name])
end
Everything seems fine . Like
If i go to localhost/hello its works.
But if i go to localhost/hello.world it gives error and says that undefined method posts for nil:NilClass And it also says
Parameters:
{"user_name"=>"hello",
"format"=>"world"}
But we know user_name should be hello.world
Then why is this error ?? :(
Clearly I think this line is creating problem
#user = User.find_by(user_name: params[:user_name])
How to fix it :( really annoying problem :(
This is a combination of two problems:
You are using find_by instead of find_by!. The normal version won't raise an ActiveRecord::RecordNotFoundException when it can't find the record, which would gracefully make rails respond with a 404 and aport the before_action, which means #user ends up set to nil, and so you can't call .posts on it.
As #davidwessman has pointed out in the comments, you can't use dots by default on Rails routes. I suspect you have a record with name hello.world, but it's trying to find just hello and so it can't find anything.

How to override index in ActiveAdmin without has_many relationshisp

I have a relation between my model User and Request that is decoupled. I.E. There is no user_id field in the requests table.I have a finder to figure out what Requests a User can see that is different than the default ActiveAdmin call of
requests where user_id = x
I had assumed that if I had a method in my User class called requests that called this finder, ActiveAdmin would be able to figure it out but it doesn't. So here's some code. I previously assumed this would work to get the requests for the user:
class User
...
def requests
RequestFinder.new(self).find
end
...
end
Then I got this error:
PG::UndefinedColumn: ERROR: column requests.user_id does not exist
LINE 1: ...T 1 AS count_column FROM "requests" WHERE "requests"...
So I figured I should override the index method in the requests controller:
def index
#requests = RequestFinder.new(current_user).find.page(params[:page]).per(20)
end
But then I get the following error:
First argument in form cannot contain nil or be empty
vendor/bundle/ruby/2.2.0/gems/actionview-4.2.4/lib/action_view/helpers/form_helper.rb:432:in `form_for'
I'm not really sure how to reformat my requests controller to render the requests from the finder instead of from the user.
So as per usual I figure it out right after I post #facepalm.
If you want to pass any generic ActiveRecord::Relation to active admin index, just override the scoped_collection method making sure to add pagination, like so:
controller do
def scoped_collection
RequestFinder.new(current_user).find.page(params[:page]).per(20)
end
end

NoMethodError in Rails while saving data

Checks_controller
class Checkscontroller < ApplicationController
def show
#check= Tester.find(params[:id])
end
def new
end
def create
#check = Tester.new(check_params)
#check.save
redirect_to #check
end
def check_params
params.require(:check).permit(:title, :description)
end
end
I am trying to save the data in 'checks' controller to 'Tester' model, getting "NoMethodError in ChecksController#create", undefined method tester_url' for#` while trying to save the data to my DB. There seems to be some issue on this line: "redirect_to #check".
Routes.rb
Rails.application.routes.draw do
get 'home/screen'
resources :checks
root 'home#screen'
end
EDIT: I see this answer got accepted. To anyone else looking at this: PLEASE DO NOT DO THIS WITHOUT A REALLY GOOD REASON.
Ok, so since you want to use the ChecksController for your Tester model, you'll have to add this to your routes: note that I'm assuming that you do not have a Check model, since I don't see it anywhere and youre using Tester as a check?
resources :testers, as: 'checks' controller: 'checks'
This line will make it so that /checks/1 goes to a Tester object with ID: 1, and use the ChecksController show method to show it
Old answer, for posterity
You're getting this error because you're missing routes for your Tester model in your routes.rb file.
You could add resources :testers to it and it will work. Of course you also already need AT LEAST your TestersController to exist with a show action
This error is occurring because when you redirect_to #check, Rails knows it's a Tester object and expects a route called tester to route to TestersController#show. It's attempting to use a helper method that rails creates for routes, called tester_url

Unable to edit database entry

So I have this application, where you create a user and then you can add movies and shows into a database. Like a bad version on IMDB?
Now.. I have this controller: https://github.com/Veske/form/blob/ryhm/app/controllers/movies_controller.rb
I have set up routes for movies and also it has all the necessary view files.. but when I attempt to go on a page to edit one of the movies: http://whatever.com/shows/1/edit for example, it gives me a error:
Couldn't find User with id=1
def correct_user
#user = User.find(params[:id])
redirect_to root_url unless current_user?(#user)
end
end
params
{"id"=>"1"}
Now.. why is it thinking that the param I throw at it, is a #user param when I have a update and edit controller made specially for Movies?
You don't seem to understand routes. The context in which you are using params[:id] is the movies controller, hence, the id would be the movie id. At the same time, you're authenticating (?) with the same param, giving you the error.
For basic authentication you could use the session hash, and for a more advanced one there are lots of gems, being devise the most popular.
PS: use rake routes to check your available routes and its URL params.
Your shows_controller.rb file calls correct_user before running the edit action you are calling, and it is specifically looking for a user on line 70. So it would make sense that you are getting this error if there is no user with an ID of 1.
Why is it thinking that the param I throw at it, is a #user param when I have a update and edit controller made specially for Movies?
Because you have a before_action filter at the top of your controller that is being called on the edit action.
You get into the correct_user method, which is using finding a user based on params[:id] . To test that this is your actual problem, you might want to try to change line 68 in your controller to:
#user = User.last #quick fix
The above could be used as a quick fix -you shouldn't get that error you posted about any more, as long as your user is signed in. If this allows you to avoid the error, you then need to concern yourself with properly assigning this User#id value when this correct_user method is called by your controller.
This is a MoviesController, so the params[:id] is actually the movie_id, i.e., the number "1" in your url "http://whatever.com/shows/1/edit". Not the user_id. So it throws the exception at line #user = User.find(params[:id]).
I went through your code but can't find where the correct user_id should come from. The Movie model doesn't belongs_to user. You should check out where the user come from.

Rails4 new template .erb creation Not Happening

I have generated scaffold and created a view called "appointment"
I wanted to added a template .erb file called inbox_mail.html.erb in appointment folder.
I did setting like this.
route.rb
get '/appointments/inbox_mail'
In appointment controller
class AppointmentsController < ApplicationController
def inbox_mail
end
end
Now running the link 3000/appointments/inbox_mail
but giving rise error as,
Mongoid::Errors::DocumentNotFound in AppointmentsController#show
Problem: Document(s) not found for class Appointment with id(s) delete_appointment. Summary: When calling Appointment.find with an id or array of ids, each parameter must match a document in the database or this error will be raised. The search was for the id(s): delete_appointment ... (1 total) and the following ids were not found: delete_appointment. Resolution: Search for an id that is in the database or set the Mongoid.raise_not_found_error configuration option to false, which will cause a nil to be returned instead of raising this error when searching for a single id, or only the matched documents when searching for multiples.
Help me in Rails4...!!!!
May be this is b'z of
def set_appointment
#appointment = Appointment.find(params[:id])
end
Yes, it is because of set_appointment method. I guess you should add :id segment to your route, like
match '/appointments/delete_appointment/:id', to: 'appointments#delete_appointment', via: :get
and this should work.
Delete something shouldn't be done through GET, you should use the DELETE method. So, when you create the link with "link_to" you should do:
link_to 'Delete appointment', delete_appointment_path(#appointment.id), method: :delete
you need a route like:
delete '/appointments/delete_appointment/:id', to: 'appointments#delete_appointment'
Then rails will take care of that and do a DELETE request with the appointment's id, then on your controller you can use #appointment = Appointment.find(params[:id])
You may want some kind of validation to render a "not found" template:
def delete_appointment
unless #appointment = Appointment.find(params[:id])
redirect_to appointment_not_found_path #something_like_that
end
end
EDIT: it looks like some before_filter is messing up there too, you talked about "delete_appointment", the error say the action called is "show" and you copied the code for the action/before_filter "set_appointment", check that first
EDIT 2: you say you are not doing any delete, then use get, the important part is the :id on the url if you need to find an appointment by an ID you need that on the url. If you don't need the ID then check your before filters, I guess you have something like
before_filter :set_appointment
you may want to skip that filter on delete_appointment
before_filter :set_appointment, except: :delete_appointment

Resources