good writing in Ruby...

J

Josselin

I know I can write it the 'ugly common way' (loop)
but I'd like to see how it can be done the Ruby way ... (I am a newbie...)

here is an array
roles = [ "a", "b", "c", "d", "e" ]

Depending upon a variable 'user.role',
I would like to suppress all elements in the array , less or equal to
this variable

ex :
user.role = "a" #=> roles = ["b", "c", "d", "e" ] "a" deleted
user.role = "b" #=> roles = ["c", "d", "e" ] "a", "b" deleted
user.role = "c" #=> roles = [ "d", "e" ] "a", "b", "c" deleted
user.role = "d" #=> roles = [ "e" ] "a", "b", "c", "d" deleted
user.role = "e" # do nothing

thanks for your tips

Joss
(I am on my way to buy the Ruby Recipes PDF Cookbook...)
 
R

Robert Klemme

I know I can write it the 'ugly common way' (loop)
but I'd like to see how it can be done the Ruby way ... (I am a newbie...)

here is an array
roles = [ "a", "b", "c", "d", "e" ]

Depending upon a variable 'user.role',
I would like to suppress all elements in the array , less or equal to
this variable

ex :
user.role = "a" #=> roles = ["b", "c", "d", "e" ] "a" deleted
user.role = "b" #=> roles = ["c", "d", "e" ] "a", "b" deleted
user.role = "c" #=> roles = [ "d", "e" ] "a", "b", "c"
deleted
user.role = "d" #=> roles = [ "e" ] "a", "b", "c",
"d" deleted
user.role = "e" # do nothing

thanks for your tips

Joss
(I am on my way to buy the Ruby Recipes PDF Cookbook...)

Do you actually want to modify the array or do you just want to work
with the reduced set? Does this help?
roles = %w{a b c d e f} => ["a", "b", "c", "d", "e", "f"]
roles.select {|r| r >= "c"} => ["c", "d", "e", "f"]
roles.select {|r| r > "c"} => ["d", "e", "f"]
roles => ["a", "b", "c", "d", "e", "f"]
roles.delete_if {|r| r <= "c"} => ["d", "e", "f"]
roles
=> ["d", "e", "f"]

Kind regards

robert
 
P

Philip Hallstrom

I know I can write it the 'ugly common way' (loop)
but I'd like to see how it can be done the Ruby way ... (I am a newbie...)

here is an array
roles = [ "a", "b", "c", "d", "e" ]

Depending upon a variable 'user.role',
I would like to suppress all elements in the array , less or equal to this
variable

ex :
user.role = "a" #=> roles = ["b", "c", "d", "e" ] "a"
deleted
user.role = "b" #=> roles = ["c", "d", "e" ] "a", "b"
deleted
user.role = "c" #=> roles = [ "d", "e" ] "a", "b", "c"
deleted
user.role = "d" #=> roles = [ "e" ] "a",
"b", "c", "d" deleted
user.role = "e" # do nothing

Maybe...

roles = roles.map {|x| x <= user.role ? x : nil }.compact

haven't tested it though...
 
J

James Edward Gray II

Depending upon a variable 'user.role',
I would like to suppress all elements in the array , less or equal
to this variable

ex :
user.role = "a" #=> roles = ["b", "c", "d", "e" ] "a" deleted
user.role = "b" #=> roles = ["c", "d", "e" ] "a", "b" deleted
user.role = "c" #=> roles = [ "d", "e" ] "a", "b", "c" deleted
user.role = "d" #=> roles = [ "e" ] "a", "b", "c", "d"
deleted
user.role = "e" # do nothing

See if this gives you some ideas:
class User
def initialize
@roles = %w[a b c d e]
@role = nil
end
?> attr_accessor :role
?> def roles
return @roles if @role.nil? or not (i = @roles.index(@role))
?> @roles[0...i]
end
end => nil
user = User.new
=> # said:
user.roles => ["a", "b", "c", "d", "e"]
user.role = "c" => "c"
user.roles
=> ["a", "b"]

James Edward Gray II
 
P

Paolo Negri

Some more infos about what are the relations among the User class and
the roles array would be nice.

Anyway you can easily rewrite your role= method of the User class to
something like this

def role=(value, array)
self.role = array.delete value if array.member? value
end

or, if you are happy to end up with a role of nil in case the role is
invalid/already given away

def role=(value, array)
self.role = array.delete value
end
 
D

Daniel Schierbeck

Josselin said:
I know I can write it the 'ugly common way' (loop)
but I'd like to see how it can be done the Ruby way ... (I am a newbie...)

here is an array
roles = [ "a", "b", "c", "d", "e" ]

Depending upon a variable 'user.role',
I would like to suppress all elements in the array , less or equal to
this variable

ex :
user.role = "a" #=> roles = ["b", "c", "d", "e" ] "a" deleted
user.role = "b" #=> roles = ["c", "d", "e" ] "a", "b" deleted
user.role = "c" #=> roles = [ "d", "e" ] "a", "b", "c"
deleted
user.role = "d" #=> roles = [ "e" ] "a", "b", "c",
"d" deleted
user.role = "e" # do nothing

I'm not quite sure I understand your problem. Is this what you're
looking for?

roles = %w{a b c d e}
user.role = "c"

# non-destructive:
roles.select{|role| role > user.role } #=> ["d", "e"]
roles #=> ["a", "b", "c", "d", "e"]

# destructive:
roles.delete_if{|role| role <= user.role }
roles #=> ["d", "e"]


Cheers,
Daniel
 
C

Chad Perrin

I know I can write it the 'ugly common way' (loop)
but I'd like to see how it can be done the Ruby way ... (I am a newbie...)

here is an array
roles = [ "a", "b", "c", "d", "e" ]

Do the "roles" have to be those letters, or did you just use them to
illustrate what you're doing? If you can use numbers for "roles"
instead, a whole new realm of possibilities opens up using comparison
operators.
 
D

Daniel Schierbeck

Chad said:
I know I can write it the 'ugly common way' (loop)
but I'd like to see how it can be done the Ruby way ... (I am a newbie...)

here is an array
roles = [ "a", "b", "c", "d", "e" ]

Do the "roles" have to be those letters, or did you just use them to
illustrate what you're doing? If you can use numbers for "roles"
instead, a whole new realm of possibilities opens up using comparison
operators.

Actually,

"b" > "a" => true
"a" < "b" => true
"a" <=> "b" => -1


Cheers,
Daniel
 
J

Josselin

Chad said:
I know I can write it the 'ugly common way' (loop)
but I'd like to see how it can be done the Ruby way ... (I am a newbie...)

here is an array
roles = [ "a", "b", "c", "d", "e" ]

Do the "roles" have to be those letters, or did you just use them to
illustrate what you're doing? If you can use numbers for "roles"
instead, a whole new realm of possibilities opens up using comparison
operators.

Actually,

"b" > "a" => true
"a" < "b" => true
"a" <=> "b" => -1


Cheers,
Daniel

no, it was just for illustration.... roles are full string names...
'god' 'administrator' 'manager', 'owner', 'customer'
Initially I thought using an additional integer field as a 'priority'
'god' priority > 'administrator' priority > etc....

the objective is presenting a collection for select option depending
upon the current_user role
if 'god' then all collection (he can CRUD any role)
if 'admin' then all collection - 'god' and 'admin'
......
 
J

Josselin

I know I can write it the 'ugly common way' (loop)
but I'd like to see how it can be done the Ruby way ... (I am a newbie...)

here is an array
roles = [ "a", "b", "c", "d", "e" ]

Do the "roles" have to be those letters, or did you just use them to
illustrate what you're doing? If you can use numbers for "roles"
instead, a whole new realm of possibilities opens up using comparison
operators.

yeah see my answer to Daniel... I believe adding an integer priority
field will be easier (sure.. if I need to add new roles later...)
thanks
 
J

Josselin

Some more infos about what are the relations among the User class and
the roles array would be nice.

Anyway you can easily rewrite your role= method of the User class to
something like this

def role=(value, array)
self.role = array.delete value if array.member? value
end

or, if you are happy to end up with a role of nil in case the role is
invalid/already given away

def role=(value, array)
self.role = array.delete value
end


I know I can write it the 'ugly common way' (loop)
but I'd like to see how it can be done the Ruby way ... (I am a newbie...)

here is an array
roles = [ "a", "b", "c", "d", "e" ]

Depending upon a variable 'user.role',
I would like to suppress all elements in the array , less or equal to
this variable

ex :
user.role = "a" #=> roles = ["b", "c", "d", "e" ]
"a" deleted
user.role = "b" #=> roles = ["c", "d", "e" ] "a",
"b" deleted
user.role = "c" #=> roles = [ "d", "e" ] "a",
"b", "c" deleted
user.role = "d" #=> roles = [ "e" ]
"a", "b", "c", "d" deleted
user.role = "e" # do nothing

thanks for your tips

Joss
(I am on my way to buy the Ruby Recipes PDF Cookbook...)

in this particular case, 'roles' array is built from the table 'roles',
all values are possible roles for a new user so I don't modify the database
this 'roles' array is presented as select options,

'roles' array content is based on current_user.role
if current_user.role is 'god' then all collection (he can CRUD any
role) is presented
if current_user.role is 'admin' then all collection minus 'god' and
'admin' (an admin cannot create god users or admini users)....

thanks
 
M

Martin DeMello

I know I can write it the 'ugly common way' (loop)
but I'd like to see how it can be done the Ruby way ... (I am a newbie...)

here is an array
roles = [ "a", "b", "c", "d", "e" ]

Do the "roles" have to be those letters, or did you just use them to
illustrate what you're doing? If you can use numbers for "roles"
instead, a whole new realm of possibilities opens up using comparison
operators.

yeah see my answer to Daniel... I believe adding an integer priority
field will be easier (sure.. if I need to add new roles later...)
thanks

You could make a Role class, define a <=> operator and mix in Comparable.

martin
 
J

Josselin

I know I can write it the 'ugly common way' (loop)
but I'd like to see how it can be done the Ruby way ... (I am a newbie...)

here is an array
roles = [ "a", "b", "c", "d", "e" ]

Depending upon a variable 'user.role',
I would like to suppress all elements in the array , less or equal to
this variable

ex :
user.role = "a" #=> roles = ["b", "c", "d", "e" ] "a" deleted
user.role = "b" #=> roles = ["c", "d", "e" ] "a", "b" deleted
user.role = "c" #=> roles = [ "d", "e" ] "a", "b", "c" deleted
user.role = "d" #=> roles = [ "e" ] "a", "b", "c", "d" deleted
user.role = "e" # do nothing

Maybe...

roles = roles.map {|x| x <= user.role ? x : nil }.compact

haven't tested it though...

I'll test it, values in array are strings : 'god', 'administrator',
''manager', 'owner', 'customer'
exclusion is based on a prority order
if current_user role is 'god' then exclude 'god' (there can be only one god)
if current_user role is 'administrator' then exclude 'god' and 'administrator'
if current_user role is 'manager' then exclude 'god' and
'administrator' and 'manager'
if current_user role is 'owner' then exclude 'god' and 'administrator'
and 'manager' and 'owner'
....
as roles could change in the future (and also ro avoid possible
localization issues) I believe it would be better to work with an
additional integer priority field in the 'role' table, so I can sort
the collection on priority and get a sorted roles array whatever is in
the table...
thanks
 
J

Josselin

I know I can write it the 'ugly common way' (loop)
but I'd like to see how it can be done the Ruby way ... (I am a newbie...)

here is an array
roles = [ "a", "b", "c", "d", "e" ]

Depending upon a variable 'user.role',
I would like to suppress all elements in the array , less or equal to
this variable

ex :
user.role = "a" #=> roles = ["b", "c", "d", "e" ] "a" deleted
user.role = "b" #=> roles = ["c", "d", "e" ] "a", "b" deleted
user.role = "c" #=> roles = [ "d", "e" ] "a", "b", "c" deleted
user.role = "d" #=> roles = [ "e" ] "a", "b",
"c", "d" deleted
user.role = "e" # do nothing

thanks for your tips

Joss
(I am on my way to buy the Ruby Recipes PDF Cookbook...)

Do you actually want to modify the array or do you just want to work
with the reduced set? Does this help?
roles = %w{a b c d e f} => ["a", "b", "c", "d", "e", "f"]
roles.select {|r| r >= "c"} => ["c", "d", "e", "f"]
roles.select {|r| r > "c"} => ["d", "e", "f"]
roles => ["a", "b", "c", "d", "e", "f"]
roles.delete_if {|r| r <= "c"} => ["d", "e", "f"]
roles
=> ["d", "e", "f"]

Kind regards

robert

thanks I'll look over it .. I'll check how it works with string values
 
J

Justin Collins

Josselin said:
<snip>
I'll test it, values in array are strings : 'god', 'administrator',
''manager', 'owner', 'customer'
exclusion is based on a prority order
if current_user role is 'god' then exclude 'god' (there can be only
one god)

It's a monotheistic system then? ;)

-Justin
 
J

Josselin

On Fri, Aug 11, 2006 at 01:20:08AM +0900, Josselin wrote:
I know I can write it the 'ugly common way' (loop)
but I'd like to see how it can be done the Ruby way ... (I am a newbie...)

here is an array
roles = [ "a", "b", "c", "d", "e" ]

Do the "roles" have to be those letters, or did you just use them to
illustrate what you're doing? If you can use numbers for "roles"
instead, a whole new realm of possibilities opens up using comparison
operators.

yeah see my answer to Daniel... I believe adding an integer priority
field will be easier (sure.. if I need to add new roles later...)
thanks

You could make a Role class, define a <=> operator and mix in Comparable.

martin

thanks Martin, that's what I finally did... writing my own Role class
(the original one was part of an authorization plugin... did not have
some much control over it )

joss
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top