{"id":232,"date":"2011-01-27T14:46:18","date_gmt":"2011-01-27T14:46:18","guid":{"rendered":"http:\/\/nicholshayes.co.uk\/blog\/?p=232"},"modified":"2011-01-27T14:46:18","modified_gmt":"2011-01-27T14:46:18","slug":"model-inhertiance","status":"publish","type":"post","link":"http:\/\/nicholshayes.co.uk\/blog\/?p=232","title":{"rendered":"Model inhertiance"},"content":{"rendered":"<p>I&#8217;m working on an application with some CMS features. One requirement is that new content is moderated before being published. To enable this, some users are allocated as moderators. To achieve this I have a moderator status column which can be either &#8216;some&#8217; or &#8216;all&#8217; (at the moment a &#8216;some&#8217; moderator can only moderate content in some languages). Up until now it hasn&#8217;t be too cumbersome to have user methods associated with moderaters defined within the User class, but now I&#8217;m getting to the point where it would be good to split some of this functionality out into a separate class.<\/p>\n<p>My problem was how to connect a new Moderator class to the User class. <\/p>\n<p>A starting point is that I want Moderator class to inherit from User. That&#8217;s simple:<\/p>\n<div class=\"codecolorer-container ruby default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"ruby codecolorer\">Moderator <span class=\"sy0\">&lt;<\/span> User<br \/>\n<span class=\"kw1\">end<\/span><\/div><\/div>\n<p>The problem with this is if you do Moderator.find(:all) you get all users and not just those who are moderators.<\/p>\n<p>In my last project, I overrode find, but that was a Rails 2 project and the same technique doesn&#8217;t work so well for this Rails 3 project. For example, Moderator.all still returns all users.<\/p>\n<p>Another option would be to use &#8216;Single Table Inheritance&#8217; (see <a href=\"http:\/\/api.rubyonrails.org\/classes\/ActiveRecord\/Base.html\">ActiveRecord::Base api<\/a>), but that would mean adding a new field and then limiting users to just one sub-class. For example, I think I will use the same technique with admins, and what if a moderator is both a moderator and an admin. Single Table Inheritance won&#8217;t let you do that.<\/p>\n<p>In the end the solution was ridiculous simple. It is <a href=\"http:\/\/api.rubyonrails.org\/classes\/ActiveRecord\/Base.html#method-c-default_scope\">&#8216;default_scope&#8217;<\/a>.<\/p>\n<p>This works<\/p>\n<div class=\"codecolorer-container ruby default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"ruby codecolorer\"><span class=\"kw1\">class<\/span> Moderator <span class=\"sy0\">&lt;<\/span> User<br \/>\n&nbsp; default_scope where<span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;moderation_scope IN (?)&quot;<\/span>, <span class=\"br0\">&#91;<\/span><span class=\"st0\">'all'<\/span>, <span class=\"st0\">'some'<\/span><span class=\"br0\">&#93;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<span class=\"kw1\">end<\/span><\/div><\/div>\n<p>And this is what I ended up with:<\/p>\n<div class=\"codecolorer-container ruby default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"ruby codecolorer\"><span class=\"kw1\">class<\/span> User <span class=\"sy0\">&lt;<\/span> <span class=\"re2\">ActiveRecord::Base<\/span><br \/>\n<br \/>\n&nbsp; MODERATE_ALL_SCOPE = <span class=\"st0\">'all'<\/span><br \/>\n&nbsp; MODERATE_SOME_SCOPE = <span class=\"st0\">'some'<\/span><br \/>\n&nbsp; MODERATION_SCOPES = <span class=\"br0\">&#91;<\/span>MODERATE_ALL_SCOPE, MODERATE_SOME_SCOPE<span class=\"br0\">&#93;<\/span> <br \/>\n<br \/>\n&nbsp; <span class=\"kw1\">def<\/span> <span class=\"kw2\">self<\/span>.<span class=\"me1\">find_moderators<\/span><br \/>\n&nbsp; &nbsp; where<span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;moderation_scope IN (?)&quot;<\/span>, MODERATION_SCOPES<span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; <span class=\"kw1\">end<\/span><br \/>\n<span class=\"kw1\">end<\/span><br \/>\n<br \/>\n<span class=\"kw1\">class<\/span> Moderator <span class=\"sy0\">&lt;<\/span> User<br \/>\n&nbsp; default_scope find_moderators<br \/>\n<span class=\"kw1\">end<\/span><\/div><\/div>\n<p>If I have special data entries that alter behaviour, I prefer to put them into constants and use the constants within the code. That way I can change the specific data entries at a later date without having to change every instance where it is used. Hence using MODERATION_SCOPES.<\/p>\n<p>The final version also allows me to share the same code between User.find_moderators and Moderator.default_scope.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;m working on an application with some CMS features. One requirement is that new content is moderated before being published. To enable this, some users are allocated as moderators. To achieve this I have a moderator status column which can &hellip; <a href=\"http:\/\/nicholshayes.co.uk\/blog\/?p=232\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[],"_links":{"self":[{"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/232"}],"collection":[{"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=232"}],"version-history":[{"count":2,"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/232\/revisions"}],"predecessor-version":[{"id":234,"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/232\/revisions\/234"}],"wp:attachment":[{"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=232"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=232"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=232"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}