Good writing in Ruby

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…)

On 10.08.2006 18:17, Josselin wrote:

ex :
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

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…

On Aug 10, 2006, at 11:20 AM, Josselin wrote:

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
=> #<User:0x322b00 @role=nil, @roles=[“a”, “b”, “c”, “d”, “e”]>

user.roles
=> [“a”, “b”, “c”, “d”, “e”]

user.role = “c”
=> “c”

user.roles
=> [“a”, “b”]

James Edward G. II

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

Chad P. wrote:

operators.
Actually,

“b” > “a” => true
“a” < “b” => true
“a” <=> “b” => -1

Cheers,
Daniel

Josselin wrote:

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

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.

On 2006-08-10 22:56:32 +0200, Daniel S.
[email protected] said:

instead, a whole new realm of possibilities opens up using comparison
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’

On Fri, Aug 11, 2006 at 06:00:13AM +0900, Daniel S. wrote:

Actually,

“b” > “a” => true
“a” < “b” => true
“a” <=> “b” => -1

Silly me, I forgot Ruby did that.

On 2006-08-10 22:01:38 +0200, Chad P. [email protected] said:

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

On 8/11/06, Josselin [email protected] wrote:

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

On 2006-08-10 18:25:19 +0200, Philip H. [email protected]
said:

ex :
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

On 2006-08-10 18:22:50 +0200, Robert K. [email protected]
said:

Joss

roles.select {|r| r > “c”}
robert
thanks I’ll look over it … I’ll check how it works with string values

On 2006-08-10 18:37:18 +0200, “Paolo N.” [email protected] said:

or, if you are happy to end up with a role of nil in case the role is

user.role = “b” #=> roles = [“c”, “d”, “e” ] “a”,
(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

Josselin wrote:

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? :wink:

-Justin

Hi –

On Sat, 12 Aug 2006, Justin C. wrote:

Josselin wrote:

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? :wink:

But the customer is always right :slight_smile:

David

On 2006-08-11 08:39:25 +0200, “Martin DeMello” [email protected]
said:

Do the “roles” have to be those letters, or did you just use them to
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