0

I am looking to get a the number of children that meet certain criteria (is_confirmed, in this instance.) This is returned in get_confirmed_amount:

def get_confirmed_amount(reservations)
  amount = 0
  reservations.each do |reservation|
    if reservation.is_confirmed
      reservation.persons.each do
        amount = amount + 1
      end
    end
  end
end

I then calling this from the index action:

def index
  @reservations = Reservation.where(customer_id: session[:customer_id]).order(:name)
  confirmed_amount = get_confirmed_amount(@reservations)
end

I then need to pass this information to the view, but setting it as @reservations.confirmed_amount will return NoMethodError. How can I get the information to the view without having to send two instance variables to the view, or is that the only way?

5
  • fyi get_confirmed_amount isn't returning a count but reservations. Instance variables and/or instance methods are the only way to send it to the view Commented Jul 13, 2016 at 2:51
  • The problem with @reservations.confirmed_amount is @reservations isn't a Reservation object. It's an ActiveRecord Collection. There may be a way to add a method to ActiveRecord Collections, but I don't know it. Commented Jul 13, 2016 at 3:02
  • Is there a specific reason why you don't want to set an instance variable? Commented Jul 13, 2016 at 3:57
  • @CameronAziz do you only need confirmed_amount? Commented Jul 13, 2016 at 4:02
  • You can cut the get_confirmed_amount method and then paste it to the helper file of the current controller. Then from view call for the method with <%= get_confirmed_amount(@reservations) %> Commented Jul 13, 2016 at 4:15

2 Answers 2

3

As @okomikeruko has already said, setting an instance variable in the controller is the easiest way to access the data in the view.

If you really don't to do that for some reason, and assuming you also don't want to change your #get_confirmed_amount method (which I assume is a private method in your controller or else an included helper method), then you could create a helper method in your controller like this.

protected

def confirmed_amount
  return if @reservations.blank?

  get_confirmed_amount(@reservations)
end
helper_method :confirmed_amount

Another thing you could to, which would allow you to set confirmed_amount as a sort of property of the @reservations relation is this.

class ReservationsView < SimpleDelegator
  attr_accessor :confirmed_amount
end

# In your controller action
def index
  reservations = Reservation
    .where(customer_id: session[:customer_id])
    .order(:name)

  @reservations = ReservationsView.new(@reservations)
  @reservations.confirmed_amount = get_confirmed_amount(@reservations)
end

SimpleDelegator will pass all undefined methods to the Reservation ActiveRecord::Relation object, but will allow you to access the confirmed_amount value via a getter method. So in the view you can do this.

<%= @reservations.confirmed_amount %>
Sign up to request clarification or add additional context in comments.

Comments

-1

Setting the @ symbol sets it's global value within the action.

So:

@confirmed_amount = get_confirmed_amount(@reservations)

and

<%= @confirmed_amount %>

is how you would pass it along as its own variable.

3 Comments

if you're inferring global scope then no.
Right. I'm not 100% versed in rails jargon, so I am most likely using the term global wrong, but I do know without the @, it doesn't get passed to the view.
The confusion in terminology is entirely understandable. The way rails passes controller instance variables to views is not intuitive.

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.