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

Every time I submit the form I get this error: undefined method `each' for nil:NilClass. If everything is correct I can submit the form without any problems, but when there is one thing missing it gives me that error. The error sends me to this line:
views/users/new.html.haml
- #subscriptions.each do |fbs|
= fb.radio_button :subscription_id, fbs.id, class: 'radiobtn', required: true
controllers/users_controller.rb
def new
#user = Users::Business.new
#subscriptions = Businesses::Subscription.all
end
def create
#user = Users::Business.new(user_params)
if #user.save
sign_in(#user)
else
render :new
end
end

Assigns subscriptions in a create action too:
before_filter :set_subscriptions, only: %w(new create) #for edit and update if needed
private
def set_subscriptions
#subscriptions = Businesses::Subscription.all
end
Or add #subscriptions = Businesses::Subscription.all directly to create action after the saving is failed and you re-render new form.

It is happening because there is no value persisted with that model .
You can check the data into the rails console
like ,
$rails console
> Businesses::Subscription.count
And if you see that there is no data then you can write a if ... end block to check for null value and handle it.

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.

Rails undefined method 'model_name' for nil:nilClass with nested attributes

I have in my orders/edit.html.erb a form that begins like this:
<%= simple_form_for [#reservation, #order] do |f| %>
Orders Controller:
def edit
#reservation = Reservation.find_by_id(params[:reservation_id])
#order = Order.find_by_id(params[:id])
end
Association:
Reservation :has_one Order
Routes:
resources :reservations do
resources :orders
end
If my path resembles something like /reservations/10/orders/10/edit I end up getting an error from Rails saying NoMethodError in Orders#edit and undefined method 'model_name' for nil:NilClass
When I create a new order the form works perfectly fine so not sure why i'm getting an error all of a sudden, can someone help me with this issue?
Current implementation is prone to failure when the URL supplied either a reservation ID or an order ID that is not valid. Two ways to handle this:
First, let Rails do it for you:
def edit
#reservation = Reservation.find(params[:reservation_id])
#order = Order.find(params[:id])
end
This will raise an ActiveRecord::RecordNotFound error, which, in production, should lead users to your 404 page.
If you'd prefer to keep find_by_id and handle this manually, or to rescue from this error in a different way, you can do:
def edit
#reservation = Reservation.find_by_id(params[:reservation_id])
#order = Order.find_by_id(params[:id])
if #reservation.nil? || #order.nil?
raise ActiveRecord::RecordNotFound.new # Or, do something else
end
end
That would yield the same result as above ... just more code.

Rails undefined method errors showing on session controller

I am building an application in which I am trying to login using clearance.I have build login and sign up page .They are working very smooth but the problem is when I am trying to show error when user enters any wrong email or password so my <% if :session.errors.any? %> is not working .It is saying undefined method `errors' for :session:Symbol
[Session_controller]
class SessionController < ApplicationController
def new
end
def create
#session = authenticate(params)
sign_in(#session) do |status|
if status.success?
redirect_to root_path
else
render 'new'
end
end
end
private
def user_params
params.require(:session).permit(:email,:password)
end
end
[session/_form.html.erb]
You are calling errors on :session, which is a symbol.
You may want to try calling errors on #session.
undefined method `errors' for :session:Symbol
errors should be called on a new model instance i.e, Model.new. You should have #session defined as Session.new in new method, the below should work
#session_controller
def new
#session = Session.new
end
#in the view
<% if #session.errors.any? %>

Rails NoMethodError undefined method `data' for nil:NilClass (Controller#update)

Edit: it turns out I made a very simple mistake and had a Template that was associated with a LocalTemplate id that no longer existed. If anyone has this problem and thinks that they somehow are unable to unable to associate the id of another model in their update action, make sure that you didn't accidentally delete the parent object causing that id to no longer exist!
The code below, while dramatically simplified did work for me.
I have a Template model in my rails app. It has a method "data" defined in it.
I am able to access this method in the create and show actions with #template.data, however when using the same #template.data in the update action of my controller I get a no method error because I am not showing the correct local template id to it. This line can be found in the model where it reads base_data = YAML.load(local_template.data)
I stored an id of the associated local_template when initially saving a new template, but how can I make sure I reference that id again in the update action so I do not get a no method error?
Here is a simplified version of the Template model and controller
Model:
class Template < ActiveRecord::Base
def data
base_data = YAML.load(local_template.data)
# couldn't pass the correct LocalTemplate here because
# the local_template_id I had in my Template model no
# longer existed. Changing the id to a LocalTemplate
# that did exist fixed the issue.
end
end
Controller:
class TemplatesController < ApplicationController
def index
#business = Business.find(params[:business_id])
#templates = #business.templates.all
end
def new
#business = Business.find(params[:business_id])
#local_templates = LocalTemplate.all
#template = #business.templates.build
end
def create
#business = Business.find(params[:business_id])
#local_templates = LocalTemplate.all
#template = #business.templates.build(template_params)
if #template.save
#template.data #works fine here
redirect_to business_url(#template.business_id)
else
render 'new'
end
end
def show
#business = Business.find(params[:business_id])
#template = #business.templates.find(params[:id])
#template.data #works fine here too
end
def edit
#business = Business.find(params[:business_id])
#local_templates = LocalTemplate.all
#template = #business.templates.find(params[:id])
end
def update
#business = Business.find(params[:business_id])
#template = #business.templates.find(params[:id])
if #template.update_attributes!(pass_template_params)
Api.new.update_template(#template.data.to_json) #this is where I had a problem
redirect_to business_url(#template.business_id)
else
render 'edit'
end
end
end
You are mixing a lot. There is a lot to refactor in your controller...
First of all, your TemplatesController should be about the template resources, but your controller looks more like a BusinessesController. In general your update action for example should look more like:
def update
#template = Template.find params[:id]
#template.attributes = template_params # though this should raise a NoMethodError, because you dind't define it; I'd prefer params[:template] if possible
if #template.save
redirect_to business_url(#template.business_id)
else
#local_templates = LocalTemplate.all
render 'edit'
end
end
Instantiating #business and #local_templates makes non sense, because you don't use it at all. Speed up your responses if you can! :)
Fixed that, there is no need for the overhead of a nested resource in update (as you did).
If saving #template fails for validation reasons, you better should load the business object late by:
#template.business
in your /templates/edit.html.erb partial. Then you also do not need a nested route to your edit action... You see, it cleans up a lot.
As a general guideline you should create as less as possible controller instance variables.
If you cleaned up your controller and views, debugging your data issue will be easier.
I assume:
local_template
in your Template model to be an associated LocalTemplate model object. So it should no issue to call that anywhere if you ensured the referenced object exists:
class Template < ActiveRecord::Base
def data
return if local_template.nil?
YAML.load(local_template.data)
end
end
or validate the existence of the local_template object. or even b
You should confirm #template is not nil, if #template is nil, you can't use data method.
1.9.3-p547 :024 > nil.data
NoMethodError: undefined method `data' for nil:NilClass
from (irb):24
from /Users/tap4fun/.rvm/rubies/ruby-1.9.3-p547/bin/irb:12:in `<main>'
And you should use update_attributes!, it can raise an exception if record is invalid.
You can do like this.
if #template
#template.update_attributes!(template_params)
#template.data
end

before_filter to set primary key before create

I am using filter to set the primary key of an instance before saving it.
Here is my controller method:
class ReferencesController < ApplicationController
before_filter :set_primary_key, :only => [:create_sub_reference]
def create_sub_reference
#reference = Reference.new(params[:reference])
respond_to do |format|
if #reference.save
format.js
else
flash[:notice] = "Reference failed to save."
end
end
end
private
def set_primary_key
result = ActiveRecord::Base.connection.execute('SELECT REF_ID FROM SEQUENCES')
inc_result = (result.fetch_row.first)
self.REF_ID = inc_result
end
end
end
I am getting the following error message in the log file when i click on the 'Save button':
NoMethodError (undefined method `REF_ID=' for #<ReferencesController:0xb69f4ca8>):
Thanks for any suggestion on this matter
You're trying to set the REF_ID attribute - which I assume is a database column - on your Controller, not your model. That code will be invoked every time a web request for ReferencesController reaches your app.
Perhaps you wanted to move the logic to a before_create hook in the References model?

Resources