-1

My goal is to fill an html table in a view (schedule.html.haml):

 - if @plans != nil
   %p display this if plans is not null
 - if @plans == nil
   %p= action_name

with the data from @plans in a controller:

def schedule
 @plans = Order.all
end

I am sure Order.all returns data. Route file is:

get 'schedule', to: 'order_articles#schedule'

When I try to do this plans is null. The output is:

schedule

I tried to check if plans is null with the code in the view. What did I do wrong?

4
  • 1
    Please provide a minimal reproducible example. What is the route and controller action? How are you calling it? What is being rendered? Your code snippet does not provide enough information for anyone to help. Commented Apr 3, 2018 at 9:17
  • Nothing in your above code indicates that @plans would be nil. It should always be a (potentially empty) array. So there must be something wrong with how you're calling the controller action/setting the variable, but I don't know what. Commented Apr 3, 2018 at 9:20
  • 1
    @Elyasin That won't make a difference. nil is the singleton instance of NilClass; checking #nil? is exactly the same thing as checking == nil. Commented Apr 3, 2018 at 9:21
  • @F. LK, I don't think it will be effective evaluating using nil, see my answer below explained how. Commented Apr 3, 2018 at 9:44

2 Answers 2

1

Ruby has a stricter and more sane type coercion scheme than other popular dynamic languages:

irb(main):001:0> !!nil
=> false
irb(main):002:0> !![]
=> true
irb(main):003:0> !!""
(irb):3: warning: string literal in condition
=> true
irb(main):004:0> !!0
=> true

Everything except nil and false evaluate to true. nil is only equal to nil.

Order.all will never return nil, if no records are found it returns an empty ActiveRecord::Collection object. It's an array like result object telling you there was nothing in the database.

So when dealing with collections you need to use the appropriate methods such as .any?, .none? etc:

- if @plans.any?
   %p display this if there are any plans.
- else
   %p= action_name
Sign up to request clarification or add additional context in comments.

Comments

0

You should use present?, any? or none? instead of nil?.

If you evaluate with nil?, it will always return false because it always return empty array [] if the object does not have any record.

For example:

Your Order table doesn't have any record.

=> @plans = Order.all
=> @plans.nil?
=> false

=> @plans
=> []

And if it has any record?

=> @plans = Order.all
=> @plans.nil?
=> false

=> @plans
=> [#<Order:0x007fa2832c0308
 id: 1,
 your_field: 'value'>]

Suggestion #1

View (schedule.html.haml):

- if @plans.present?
  %p display this if plans is not null
- else
  %p= action_name

Suggestion #2

View (schedule.html.haml):

- if @plans.any?
  %p display this if plans is not null
- else
  %p= action_name

Suggestion #3

View (schedule.html.haml):

- if @plans.none?
  %p= action_name
- else
  %p display this if plans is not null

1 Comment

I would say any? or none? reads much better. .present? is really for checking if the value/key is set and is not a blank value.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.