Grails has the concept of chaining actions. Is it possible to do the
same
within Rails?
In other words, if I had the following:
class MyController < ApplicationController
def x
render (:template=>‘x’)
end
def y
render(:template=>‘y’)
end
#would it be possible to have an action that did?
def xORy
if something==true
render(:action=>:x)
else
render(:action=>:y)
end
end
end
Note, render(:action) is just my idea of how it might work…I’m not
implying that it’s valid syntax.
If this is not something readily available in Rails, what do you do to
emulate? Surely it’s a common pattern to need to “chain” a sequence of
action calls?
Also, I find that in a more complex example, this makes like difficult
and
forces you to be more explicit:
Let’s say I’m using the implicit template rendering in x and y. Calling
x or
y will break down in this case…you have to explicitly call
render(:template=“controllername/x”) if you call x() as a method.
Also, let’s say we have a method like this:
def do_something_conditionally @choices = params[:choices] @choices.each do |one_choice|
if one_choice.nil? or one_choice.empty?
x()
end
end
flash[:notice] = “Param check passed…we’ll continue a render
implicit
template here”
end
This won’t work because, because even though you call x(), the
processing of
the rest of the logic doesn’t stop. So, you’d have to do something like:
def do_something_conditionally @choices = params[:choices]
passed = true @choices.each do |one_choice|
if one_choice.nil? or one_choice.empty?
passed=false
break
end
end
if !passed
x()
else
flash[:notice] = “Param check passed…we’ll continue a render
implicit
template here”
end
end
But you’ll lose all your action’s parameters, correct? params and
session and the like?
Nope. params and the like are methods on the ActionController::Base
object and therefore are still available when you are calling another
method in the same object your action is defined in.
This won’t work because, because even though you call x(), the
processing of the rest of the logic doesn’t stop.
Of course the method you call returns and execution continues. That’s
just the way methods work. But if you want to exit early just return.
So:
def do_something_conditionally @choices = params[:choices]
x and return if @choices && @choices.any?(&:blank?)
flash[:notice] = “Param check passed…”
end
Notice that I simplified your code a bit since blank? checks for nil?
and empty? and I used any? to process the loop. But if you prefer your
more verbose method you can do the same thing:
def do_something_conditionally @choices = params[:choices] @choices.each do |one_choice|
if one_choice.nil? or one_choice.empty?
x
return
end
end
flash[:notice] = “Param check passed…”
end
Ok, so your version works, but only as long as you explicitly render
“something” in the controller you’re calling as a method. In other
words, if
I don’t define render in x(), it won’t work. I presume it has something
to
do with the backend code rails uses to support explicit templates.
Notice that I simplified your code a bit since blank? checks for nil?
end
flash[:notice] = “Param check passed…”
end
Well, first off, nice code. I love the terseness (esp the
symbol#to_proc).
Very clean.
I had actually thought before that this should work, but it didn’t for
me.
After seeing your example I have tried it both ways, to no avail. The
error
I get?
Thanks Eric, I should have thought about it being for an array - me
being a bit dim.
I often wonder how many useful methods are around that I don’t know
about. This group is very useful for picking up tidbits like that -
it’s remembering them or knowing how to cross reference them that is
difficult. (I’m getting on a bit you see and the old grey matter
dosn’t retain stuff like it used to. sometimes I just struggle to
remember where I saw something, let alone the detail of what it does.
Oh well at least we have google (except for common expressions like
any? that is.)
def do_something_conditionally @choices = params[:choices]
x and return if @choices && @choices.any?(&:blank?)
flash[:notice] = “Param check passed…”
end
OK - I give up, where did any? come from. Cant find it in the Ruby
manual, cant find it in the Rails doc and certainly cant find it by
googling. =)
Also, am I missing something cos I cant make it work?
If I have a hash {:a=>1, :b=>2, :c=>nil}
a.each {|k,v| puts v.blank?}
gives: false, false, true
but
a.any?(&:blank?)
gives: false
what am I getting wrong?
Thanks
Tonypm
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.