Forum: Ruby on Rails Writing a breakable loop? If it gets a match it should stop.

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
374eedcae1d1d978519423f315cff02d?d=identicon&s=25 W. andrew Loe iii (waloeiii)
on 2007-01-09 01:48
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.

[code]
# 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
[/code]

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.
D0cd6b10e01bacb976b3b815a9c660bc?d=identicon&s=25 Alex Wayne (squeegy)
on 2007-01-09 02:24
W. andrew Loe iii wrote:

> [code]
> # 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
> [/code]
>
> 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.
Aedb187f1ebbbc22557ade4003869afd?d=identicon&s=25 jdswift (Guest)
on 2007-01-09 02:26
(Received via mailing list)
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"
3e6bbd5a01437feec48adf3838b15d91?d=identicon&s=25 Andrew Skegg (Guest)
on 2007-01-09 02:31
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.
>
> [code]
> # 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
> [/code]
>
> 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
374eedcae1d1d978519423f315cff02d?d=identicon&s=25 W. andrew Loe iii (waloeiii)
on 2007-01-09 02:33
>
> 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!
3f7fc5fbdbb40cf38d5bf94f265b343c?d=identicon&s=25 Andrew Skegg (askegg)
on 2007-01-09 02:41
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 :)

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.
374eedcae1d1d978519423f315cff02d?d=identicon&s=25 W. andrew Loe iii (waloeiii)
on 2007-01-09 02:45
Andrew Skegg 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 :)
>
> 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.
374eedcae1d1d978519423f315cff02d?d=identicon&s=25 W. andrew Loe iii (waloeiii)
on 2007-01-09 02:46
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.
374eedcae1d1d978519423f315cff02d?d=identicon&s=25 W. andrew Loe iii (waloeiii)
on 2007-01-09 02:49
  def looper_url?(url)
    rights = Right.find(:all)
    for right in rights
      return if url_for(right) == url
    end
  end

is working as expected.
3f7fc5fbdbb40cf38d5bf94f265b343c?d=identicon&s=25 Andrew Skegg (askegg)
on 2007-01-09 02:57
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 :P  Glad to see you have it working.
1fba4539b6cafe2e60a2916fa184fc2f?d=identicon&s=25 unknown (Guest)
on 2007-01-09 03:10
(Received via mailing list)
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 (http://www.manning.com/black)
    (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)
This topic is locked and can not be replied to.