# STI with user and artist? Your thoughts please

**URL:** <https://www.ruby-forum.com/t/sti-with-user-and-artist-your-thoughts-please/195833>\
**Category:** Rails\
**Created:** [September 30, 2010, 10:52pm UTC](https://www.ruby-forum.com/t/sti-with-user-and-artist-your-thoughts-please/195833 "2010-09-30T22:52:30Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![zurich\_by\_night](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/d78d45/32.png) [@zurich\_by\_night](https://www.ruby-forum.com/u/zurich_by_night)\
**Post date:** [September 30, 2010, 10:52pm UTC](https://www.ruby-forum.com/t/sti-with-user-and-artist-your-thoughts-please/195833/1 "2010-09-30T22:52:30Z")

</div>

I’ve got user and artist. The app allows users to register. And some  
of these registered users can sign up as an artist as well.

Should user be an STI? Perhaps i can have user as an STI, member  
(registered users) and artist models that inherit from user?

My concern is, if we go ahead with the STI approach. Consider this  
scenario. A user registers. The record is saved and type=user. Later  
on the same user signs up as an artist. How would we change the type  
for this user? Should this be done in the Artist controller, create  
method? i.e. a look up will be performed, and if user found (user.type  
= ‘Artist’; user.save!)

Or should user and artist be separate tables on their own? i.e. user  
has\_one :artist, artist belongs\_to :user?

Any other better approach?

---

<div class="post-metadata">

**Author:** ![zurich\_by\_night](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/d78d45/32.png) [@zurich\_by\_night](https://www.ruby-forum.com/u/zurich_by_night)\
**Post date:** [September 30, 2010, 11:20pm UTC](https://www.ruby-forum.com/t/sti-with-user-and-artist-your-thoughts-please/195833/2 "2010-09-30T23:20:36Z")

</div>

I would go with having a boolean field for artist and then conditional  
validarions, that is , if the field is true then have validations for  
artist  
apply along with the display of those extra field in the view, if the  
user  
stops been an artist, then it would stop validating and presenting those  
field, in fact would add a validation that would forbid those fields  
from  
changing while the artist value is false.

---

<div class="post-metadata">

**Author:** ![zurich\_by\_night](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/d78d45/32.png) [@zurich\_by\_night](https://www.ruby-forum.com/u/zurich_by_night)\
**Post date:** [October 1, 2010, 8:08am UTC](https://www.ruby-forum.com/t/sti-with-user-and-artist-your-thoughts-please/195833/3 "2010-10-01T08:08:59Z")

</div>

Radhames, you are suggesting one table called user? and bolean fields  
for is\_artist, is\_member? Is that right?

---

<div class="post-metadata">

**Author:** ![zurich\_by\_night](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/d78d45/32.png) [@zurich\_by\_night](https://www.ruby-forum.com/u/zurich_by_night)\
**Post date:** [October 1, 2010, 11:13am UTC](https://www.ruby-forum.com/t/sti-with-user-and-artist-your-thoughts-please/195833/4 "2010-10-01T11:13:55Z")

</div>

I think that the whether to separate or not Artists and Users for two  
different tables depends  
on whether are the models petty similar or not. If the only difference  
is couple of new fields in the Artist  
model and few new methods then there is no need to separate the  
mapping into two tables. If there are  
a lot of non-common columns you may also try to use :polymorphic =\>  
true association.

On Sep 30, 11:51 pm, Christian F. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![zurich\_by\_night](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/d78d45/32.png) [@zurich\_by\_night](https://www.ruby-forum.com/u/zurich_by_night)\
**Post date:** [October 1, 2010, 2:13pm UTC](https://www.ruby-forum.com/t/sti-with-user-and-artist-your-thoughts-please/195833/5 "2010-10-01T14:13:01Z")

</div>

in case you wan to go with STI, create a controller to change type, and  
access the attribute like this user[:type], not user.type

---

<div class="post-metadata">

**Author:** ![zurich\_by\_night](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/d78d45/32.png) [@zurich\_by\_night](https://www.ruby-forum.com/u/zurich_by_night)\
**Post date:** [October 1, 2010, 2:10pm UTC](https://www.ruby-forum.com/t/sti-with-user-and-artist-your-thoughts-please/195833/6 "2010-10-01T14:10:40Z")

</div>

Yes, if the member will become an artist but and artist still has all  
the  
attributes of a member, is better to have one model with conditional  
validation, something like.

validates :master\_piece, :presence =\> true, :if =\> is\_artist?

def is\_artist?  
artist  
end

and in the view i would put some

\<%= @member.master\_piece if member.is\_artist?%\>

all these IF artist are member. I would use STI if member are not artist  
but  
share a few fields like name and so, but if an artist has all the fields  
a  
member has and a few more, there is no need for STI.

---

<div class="post-metadata">

**Author:** ![zurich\_by\_night](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/d78d45/32.png) [@zurich\_by\_night](https://www.ruby-forum.com/u/zurich_by_night)\
**Post date:** [October 1, 2010, 5:59pm UTC](https://www.ruby-forum.com/t/sti-with-user-and-artist-your-thoughts-please/195833/7 "2010-10-01T17:59:00Z")

</div>

On Oct 1, 7:09 am, radhames brito [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Yes, if the member will become an artist but and artist still has all the  
> attributes of a member, is better to have one model with conditional  
> validation, something like.
> 
> validates :master\_piece, :presence =\> true, :if =\> is\_artist?
> 
> def is\_artist?  
> artist  
> end

As an aside, there’s an even nicer syntax:

validates :master\_piece, :presence =\> ture, :if =\> artist?

If “artist” is the name of a boolean column, ActiveRecord provides  
“artist?” automatically. (Also, is\_? style is more prevalent in  
Java/.NET, but not in Ruby).

Jeff
