Writing a breakable loop? If it gets a match it should stop

I’m trying to write a function that will accept a rails URL, and see if
it matches one of my Rights. Rights are just controller URLs, so I can
manage access at the controller level (don’t need action level). What
I’m trying to do is take the url passed, and see if its access
controlled. If it is, the method should stop and return true, if not it
will return false. This method is used to check when someone logs out if
they can be redirected to where they are, or if they need to be
redirected to the home URL, it protects from an infinite login loop.

# true if this is a protected url that would cause a login loop
def looper_url?(url)
  rights = Right.find(:all)
  for right in rights
  if url_for(right) == url
    return true
    exit
  end
end

This is what I came up with, it doesn’t work but it should be pretty
enough to give you an idea of what I’m trying to do. I think the problem
is just in my inner most if block, not sure how to stop the loop and
return true.

W. andrew Loe iii wrote:

# true if this is a protected url that would cause a login loop
> def looper_url?(url)
>   rights = Right.find(:all)
>   for right in rights
>   if url_for(right) == url
>     return true
>     exit
>   end
> end

This is what I came up with, it doesn’t work but it should be pretty
enough to give you an idea of what I’m trying to do.

What doesn’t work? This is exactly what the “return” statement is for.
It immediately stops executing the method its in and returns the value.
I tried this in irb and it had the desired effect

def foo
10.times do |i|
puts i
return i if i > 5
end
end

a = foo
1
2
3
4
5
6

puts a
6

as you can see, the loop is terminated as soon i is greater than 5,
since 7 8 and 9 are not printed. Perhaps your condition is never true?
Try a simpler comparison to be sure that “url_for(right) == url” isn’t
the problem instead of the return value.

You could just do:
def allowed_access?(url)
Right.find(:all).detect {|r| url_for r == url}
end

That would return nil if no match, otherwise it returns a right object.
So this would work:
if allowed_access(“url string”)
#do something
end

On Jan 9, 10:48 am, “W. andrew Loe iii”

W. andrew Loe iii wrote:

I’m trying to write a function that will accept a rails URL, and see if
it matches one of my Rights. Rights are just controller URLs, so I can
manage access at the controller level (don’t need action level). What
I’m trying to do is take the url passed, and see if its access
controlled. If it is, the method should stop and return true, if not it
will return false. This method is used to check when someone logs out if
they can be redirected to where they are, or if they need to be
redirected to the home URL, it protects from an infinite login loop.

# true if this is a protected url that would cause a login loop
> def looper_url?(url)
>   rights = Right.find(:all)
>   for right in rights
>   if url_for(right) == url
>     return true
>     exit
>   end
> end

This is what I came up with, it doesn’t work but it should be pretty
enough to give you an idea of what I’m trying to do. I think the problem
is just in my inner most if block, not sure how to stop the loop and
return true.

How about this?

def looper_url?(url)
return Right.find(:all).include?(url)
end

How about this?

def looper_url?(url)
return Right.find(:all).include?(url)
end

Thats a much clearer version of exactly what I was trying to do. Thank
you so much!

W. andrew Loe iii wrote:

How about this?

def looper_url?(url)
return Right.find(:all).include?(url)
end

Thats a much clearer version of exactly what I was trying to do. Thank
you so much!

Your welcome :slight_smile:

Looking back at you code I am not sure if it will work as you have a
call to “url_for” in there, so the results will depend on what in in the
rights array.

The more I look at it, it might be better to be able to run url_for on
the rights item then it is to get the format of the referer right.

def looper_url?(url)
rights = Right.find(:all)
for right in rights
return if url_for(right) == url
end
end

is working as expected.

Andrew S. wrote:

W. andrew Loe iii wrote:

How about this?

def looper_url?(url)
return Right.find(:all).include?(url)
end

Thats a much clearer version of exactly what I was trying to do. Thank
you so much!

Your welcome :slight_smile:

Looking back at you code I am not sure if it will work as you have a
call to “url_for” in there, so the results will depend on what in in the
rights array.

Yea, I’m tinkering with it right now. Request.referer is the url thats
gettting passed, but the “rights” are stored in the database as just the
controller name, not a complete url. I am trying if
request.referer.paramaters will work, or I’ll have to just explode and
do it by hand.

W. andrew Loe iii wrote:

The more I look at it, it might be better to be able to run url_for on
the rights item then it is to get the format of the referer right.

That would be a better option int he long run as you most likely have
other controllers that will call this procedure. Best to keep it all in
one place - dry and all.

Sorry to get your hopes up :stuck_out_tongue: Glad to see you have it working.

Hi –

On Tue, 9 Jan 2007, W. andrew Loe iii wrote:

def looper_url?(url)
rights = Right.find(:all)
for right in rights
return if url_for(right) == url
end
end

is working as expected.

If you want to make it more concise, in the style of Andrew’s
examples, you could do something like:

def looper_url?(url)
Right.find(:all).any? {|right| url_for(right) == url }
end

David


Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (Ruby for Rails)
(See what readers are saying! http://www.rubypal.com/r4rrevs.pdf)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)