2

How does one use the Ruby on Rails method performed? in an if else statement?

I tried to use this StackOverflow anwser in my example below:

if condition
  does something
elsif redirect_to(records_path)
  performed?
  does another thing
else
  yet another thing
end

But this only redirects without checking if it is performed.

I want it to check if the redirect to records_path is performed and when true do something (or "does another thing" in my example)

I also tried this:

elseif records_path.performed?

And this:

elseif redirect_to(records_path) performed?()

And all things in between.

Can somebody explain how it's done and how I could've get it from the docs?

  • Try using if statement this way: `does something if performed?` – iGian May 29 '18 at 10:04
  • By convention, Ruby/Rails methods ending in `?` shouldn't ever appear on their own like this. The `?` indicates it's a query function that doesn't alter any state, in which case putting it on its own line serves no purpose. – mahemoff May 29 '18 at 11:48
  • @mahemoff for completeness: it doesn't alter any state, _and returns a boolean_ (true or false). – nathanvda May 29 '18 at 11:51

3 Answers3

2

performed? just tests if render or redirect has already happened. That doesn't check what view was sent to the user. That check only "you define path yourself or it must be done automatically".

Try something like this:

if condition
  does something
  redirect_to(records_path)
end
if performed?
  does another thing
else
  yet another thing
end
Leo
  • 1,673
  • 1
  • 13
  • 15
  • Do you place the if-else statement in the same method or in the receiving (RecordsController index) method? EDIT: I get it now. Thank you for your effort! –  May 29 '18 at 11:55
  • If I understand you truly, it's not important – Leo May 29 '18 at 12:00
2

In a controller action, when we type render or redirect_to those are not immediately executed, but they are queued and will be executed after the completion of the method. So this allows to have double renders or redirect_to in a controller action, and this will generate an error (because then rails has no idea which to execute). So that is why in rails they have added a method performed? which will indicate if a render or redirect_to has already been called (queued) or not.

In most cases this is not really needed because normally your controller code is pretty simple.

To clarify: performed? does not actually test the redirect_to has been done, it just tests a render or redirect-to was called/queued. Furthermore the redirect_to does not return a boolean indicating whether it was done or not.

So your code should be like this:

if condition
  does something
else 
  redirect_to(records_path)
end 
if performed?
  # the redirect-to was executed
  does another thing # but not a render or redirect
else
  yet another thing 
  # and could be a render or redirect 
  # if not the normal view will be rendered
end

Please not that in this simple example the performed? is just the negative of condition so you could easily squash those together.

nathanvda
  • 49,707
  • 13
  • 117
  • 139
1

It's meant for your controller action (A) to be able to call other controller methods (M), and then render or redirect in (A) only if none of (M) have performed a render/redirect.

Read the source code, it's pretty simple and explicit: https://apidock.com/rails/ActionController/Metal/performed%3F

For example:

class ArticlesController < ApplicationController                                                                                                                                                                                  
  def show                                                                                                                                                                                                                        
    check_identity                                                                                                                                                                                                                
    render :show unless performed?                                                                                                                                                                                                
  end                                                                                                                                                                                                                             

  def check_identity                                                                                                                                                                                                              
    redirect_to root_path, notice: "You're not allowed to be here" unless user_signed_in?                                                                                                                                         
  end                                                                                                                                                                                                                             
end
yoones
  • 2,394
  • 1
  • 16
  • 20
  • Thank you for your general explanation. It certainly helps, but in reference to my original question: is this also possible in an if else statement? –  May 29 '18 at 11:13
  • @KellyHuliselan Yes, it is meant to be used in a condition. – yoones May 29 '18 at 11:30
  • Thank you for taking to time to answer my question! –  May 29 '18 at 12:00