On Sunday, November 26, 2017 at 5:38:56 PM UTC-8, Andrew Burleson wrote:
>
> I have a pattern I've used a few times with Sequel where I want to 
> represent a model attribute with a Ruby object, even though it makes sense 
> to store it as some primitive in the database (string or hash typically).
>
> Here's a contrived example: assume we have a User model with a Role 
> attribute, and Role is acting like an enum of sorts. My code might look 
> like this:
>  
> class Role
>   VALUES = %w|guest member admin|
>
>
>   def initialize(value)
>     raise "Invalid Role" unless VALUES.include?(role)
>     @value = value
>   end
>
>
>   VALUES.each do |val|
>     define_method "#{val}?" do
>       @value == val
>     end
>   end
>
>
>   def to_s
>     @value
>   end
> end
>
>
> class User < Sequel::Model
>   def role=(input)
>     @role = Role.new(input)
>     super(@role.to_s)
>   end
>
>
>   def role
>     @role ||= Role.new(super)
>   end
> end
>
> Now, this kind of thing seems to work fine, but it's a bit verbose on the 
> model side. I've been thinking about writing some class macros to reduce 
> the verbosity, but it occurred to me that I might get some input on whether 
> or not the above is a good idea or there's a better way to do this before I 
> go to that trouble.
>
> My question is just this: is there a better and/or built-in mechanism for 
> saying "this column should be cast to and serialized from ____", where in 
> my case ____ is some Ruby class.
>

The serialization or composition plugins handle something similar to what 
you want, though you would have to create a custom serializer/deserializer 
for Role (a pair of procs).

The main difference is that your code has #role returning a deserialized 
value but #role= taking serialized input.  From a modelling perspective, 
this is questionable, you would generally want deserialized input for both 
or serialized input for both.  If #role returns a Role instance, then 
#role= should take a Role instance. The serialization plugin would expect 
#role= to take a Role instance, and the composition plugin would expect 
that instead of overriding #role and #role=, you would have separate 
methods for getting/setting Role instances.

Thanks,
Jeremy

-- 
You received this message because you are subscribed to the Google Groups 
"sequel-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sequel-talk.
For more options, visit https://groups.google.com/d/optout.

Reply via email to