I'm getting
undefined method `errors' for nil:NilClass
When I made my custom validation before create new data table.
This is my code in the the controller, everything works fine before the validation method trigger.
class ActivitiesController < ApplicationController
layout 'admin'
before_action :admin_logged_in_user, only: [:create, :destroy,:edit,:update]
before_action :admin_correct_user, only:[:destroy,:update,:edit]
before_action :permanent_event_check, only:[:create,:update]
def list
end
def create
#activity = admin_current_user.activities.build(activity_param)
if #activity.save
flash[:success] = "Activity Created!"
redirect_to admin_dashboard_url
else
render 'new'
end
end
def new
#activity = Activity.new
end
private
def activity_param
params.require(:activity).permit(:name,:details,:start_at,:end_at,
:activity_image01_url,:activity_image02_url,:activity_image03_url,
:youtube_url,:capacity,:booking_status,:rules,:apply_details,
:payment_price,:payment_need,:avaliable,:rating,:temple_id)
end
def admin_correct_user
#activity = admin_current_user.activities.find_by(id: params[:id])
redirect_to admin_dashboard_url if #activity.nil?
end
def permanent_event_check
param_activity = params[:activity]
if param_activity[:permanent] == "false"
if param_activity[:start_at] == "" || param_activity[:end_at] == ""
#activity.errors[:base] << "You can't leave start and end date blank with Permanent Event"
return false
end
end
end
end
And this line.
#activity.errors[:base] << "You can't leave start and end date blank with Permanent Event"
I got the error from this line.
How to fix this?
Thanks!
******* add model file after moving validation
This is my model after i tried to move my validation but it seems like nothing in return from #activity
validate :permanent_event_check
private
def permanent_event_check
param_activity = #activity
if param_activity.permanent == "false"
if param_activity.start_at == "" || param_activity.end_at == ""
#activity.errors[:base] << "You can't leave start and end date blank with Permanent Event"
return false
end
end
end
From your before_action blocks:
before_action :admin_logged_in_user, only: [:create, :destroy,:edit,:update]
before_action :admin_correct_user, only:[:destroy,:update,:edit]
before_action :permanent_event_check, only:[:create,:update]
You have the admin_correct_user which is setting #activity before you have permanent_event_check from where you are adding the error.
However, admin_correct_user only triggers for the actions: [:destroy,:update,:edit] while permanent_event_check triggers for create and update.
The Implication of this is that for the create action, the order of events in your controller is: admin_logged_in_user (which is probably a validation) -> permanent_event_check (trying to add errors). Notice that the other action (admin_correct_user) which was meant to set #activity was skipped.
Therefore... for the create action especially, as at the point where you are trying to add the error, there is no object named #activity.
#activity is Nil
So... the reason for the error.
To fix it:
Ensure to build the #activity object before trying to access it(for validation or for any other thing).
Arup's suggestion of moving the validation into your model is a great one!
To Move it to the model:
#activity.rb:
validate :right_event
def right_event
#check validity, and add custom error here
unless permanent
errors.add(:permanent, "You can't leave start and end date blank...") unless self.start_at and self.end_at
end
end
Related
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.
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.
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? %>
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?
I have several models that I want the user to "disable" it vs destroying it. These models have a disable boolean. trying to make this work.
currently in application_controller.rb
helper_method :disable
def disable(model)
#model = "#{model}".find(params[:id])
#model.update_attribute(:disable => true)
flash[:notice] = "Successfully disabled #{model}."
redirect_to company_ + "#{model}".pluralized + _url(current_company)
end
Do I have to create a new path in routes for each one I want to use this function?
Would be ideal, if I can do something similar like the destroy method.
I would probably extend ActiveRecord with a disable method so that you can call #model.disable() just like you would #model.destroy(). That way you can leave all the default routes as is and just change the destroy action in your controller to try disable() instead of destroy().
Perhaps like this:
module MyDisableModule
def self.included(recipient)
recipient.class_eval do
include ModelInstanceMethods
end
end
# Instance Methods
module ModelInstanceMethods
#Here is the disable()
def disable
if self.attributes.include?(:disabled)
self.update_attributes(:disabled => true)
else
#return false if model does not have disabled attribute
false
end
end
end
end
#This is where your module is being included into ActiveRecord
if Object.const_defined?("ActiveRecord")
ActiveRecord::Base.send(:include, MyDisableModule)
end
And then in your controller:
def destroy
#model = Model.find(params[:id])
if #model.disable #instead of #model.destroy
flash[:notice] = "Successfully disabled #{#model.name}."
redirect_to #wherever
else
flash[:notice] = "Failed to disable #{#model.name}."
render :action => :show
end
end
Note that in this example, disabled is the attribute and disable is the method that makes a model disabled.