title: Rails: complicated design choice: polymorphism? STI?
body: <p>I have been trying different techniques while designing this application, which to me is very complicated as there are many solutions to chose from. Deciding which of these solutions is the best has become my full time job for the last few weeks.</p>
  
  <h2>Background:</h2>
  
  <p>I have a <code>User</code> model which contains some very basic authentication functionality. The application will have three different types of users; admins, buyers, and sellers. The user type will be determined during sign up, where a check box will ask if the user is a seller. If the box is checked, the user is a seller, and if the box is unchecked, it's assumed their just a buyer. I would rather not have a drop down menu to select the user type (Buyer, Seller). Easy so far.</p>
  
  <h2>Details:</h2>
  
  <p>Sellers have a profile, and users who visit the site will be able to browse through the different sellers and view their profile. Buyers do not have a profile, and should not be listed on the site for users to see. If that's not complicated enough, buyers should have the option to change their account type and become a seller. Similarly, sellers can change their account type and "deactivate" their seller account, removing them from the list of sellers.</p>
  
  <h2>Design options:</h2>
  
  <p><strong>Single table inheritance</strong>:</p>
  
  <p>What I came up with when attempting to implement this using STI was suboptimal. I was faced with two options: a messy controller, which made the decision of what type of user to create based on the check box mentioned above (one controller - UsersController), or two different sign up forms that were identical (two controllers - BuyersController, SellersController).</p>
  
  <p><strong>has_one or "has_none" Profile association</strong>:</p>
  
  <pre><code>class User &lt; ActiveRecord::Base
    has_one :profile # only if the user_type or role is "seller"
  end
  
  class Profile &lt; ActiveRecord::Base
    belongs_to :user
  end
  </code></pre>
  
  <p>Here I would use something like CanCan or declarative_authorization, and let the user chose his/her role via the check box mentioned above. This introduces a security risk, as there will be an admin role and I don't want this to be open for mass assignment.</p>
  
  <p>I guess either way you look at it I'll have a messy controller with conditionals on how to create the user. Unless I choose to have two check boxes ("I am a seller," and "I am a buyer"), but this seems redundant. It also seems as though whichever design I choose, I'll be faced with some hackish solutions.</p>
  
  <p>Maybe introduce some model that lies between the <code>User</code> and user type?</p>
  
  <p>Any opinions?</p>