Andrew Edwards
2009-Dec-14 16:24 UTC
Too many methods in the model? Extra lightweight logic layer?
Hi, Given the convention of fat models to handle business logic, is there a point where you might be justified in using a separate plain ruby object(s) to orchestrate certain business logic interactions, essentially a middle layer between your controllers and models for high level functions? If you look at the InventoryTransaction model below you will see the sort of methods I mean. In this case they are similar to factory methods I suppose. However, I could end up with around 30+ different method handling different kinds of inventory adjustments. Most of these methods are non-trivial as the lookup and create other models and then interact with them in achieving the desired business function. What are peoples experience with this? Leave them in the single model or extract them to plain ruby classes (possibly within the models folder) with a bunch of class methods to handle high level business logic? This would also allow grouping methods of related functionality in to separate classes. Am I heading for future issues? class InventoryTransaction < AR::Base has_many :inventory_account_entries validate :inventory_account_entries_balance def manually_add_inventory(product, location, quantity) ...create new transaction and suitable entries in to inventory accounts end def manually_remove_inventory(product, location, quantity) ...create new transaction and suitable entries in to inventory accounts end def report_shortage(product, location, quantity) ...create new transaction and suitable entries in to inventory accounts end def report_surplus(product, location, quantity) ...create new transaction and suitable entries in to inventory accounts end ... plus many more potential inventory interactions or events resulting in movement between inventory accounts and the creation of a new InventoryTransaction record end Thanks, Andrew. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Jeff
2009-Dec-14 17:00 UTC
Re: Too many methods in the model? Extra lightweight logic layer?
On Dec 14, 10:24 am, Andrew Edwards <and...-ZYDPpGlny4uS7RsuTa25KztV0T984lsv@public.gmane.org> wrote:> Hi, > > Given the convention of fat models to handle business logic, is there > a point where you might be justified in using a separate plain ruby > object(s) to orchestrate certain business logic interactions, > essentially a middle layer between your controllers and models for > high level functions?> If you look at the InventoryTransaction model below you will see the > sort of methods I mean. In this case they are similar to factory > methods I suppose. However, I could end up with around 30+ different > method handling different kinds of inventory adjustments.The idea is fat model *layer*, not necessarily fat model classes. You should feel free to factor out inventory-handling methods into separate Ruby modules or classes, and use them from within your InventoryTransaction class. That way your ActiveRecord class isn''t cluttered with lots of methods. I tend to keep such modules and pure- Ruby classes in the models directory, but some people prefer to keep them in lib/ instead. Jeff purpleworkshops.com -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Andrew Edwards
2009-Dec-14 17:34 UTC
Re: Too many methods in the model? Extra lightweight logic layer?
Thanks Jeff, makes sense. I''ve since been digging around one of my goto/"how do they tackle it" open source rails projects and see similar approaches. In this case, the Spree e-commerce platform. On 14 Dec, 17:00, Jeff <cohen.j...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On Dec 14, 10:24 am, Andrew Edwards <and...-ZYDPpGlny4uS7RsuTa25KztV0T984lsv@public.gmane.org> > wrote: > > > Hi, > > > Given the convention of fat models to handle business logic, is there > > a point where you might be justified in using a separate plain ruby > > object(s) to orchestrate certain business logic interactions, > > essentially a middle layer between your controllers and models for > > high level functions? > > If you look at the InventoryTransaction model below you will see the > > sort of methods I mean. In this case they are similar to factory > > methods I suppose. However, I could end up with around 30+ different > > method handling different kinds of inventory adjustments. > > The idea is fat model *layer*, not necessarily fat model classes. You > should feel free to factor out inventory-handling methods into > separate Ruby modules or classes, and use them from within your > InventoryTransaction class. That way your ActiveRecord class isn''t > cluttered with lots of methods. I tend to keep such modules and pure- > Ruby classes in the models directory, but some people prefer to keep > them in lib/ instead. > > Jeff > > purpleworkshops.com-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Andrew Pace
2009-Dec-15 05:46 UTC
Re: Too many methods in the model? Extra lightweight logic layer?
Agreed with Jeff. The AR models really act as a wrapper class to DB tables. This helps to add an abstraction layer to SQL and marshall SQL selects into powerful ruby objects (the best part, in my opinion). With that in mind create non-AR models as needed, and only use the AR models when the actions really relate to that table/model. A quick example. Let say you need to encrypt and decrypt fields in a single AR model. You could write your code within this model, since it is the only model that currently needs encryption. But, this will clutter the AR model with methods that don''t directly pertain to it, and it won''t scale work well if you later decide other AR models also should encrypt information. Better to add a non-AR class to work out the details. Andrew -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Wojciech Kruszewski
2009-Dec-15 19:44 UTC
Re: Too many methods in the model? Extra lightweight logic layer?
I try to keep only high-level functionality and business logic in the models. Here''s the drill: 1. identify things that are not specific to your model or application and then extract them into a plugin 2. identify things that are specific to your application, but not to your model and extract them into a lib 3. find groups of related methods that are lower level (used only in this model itself) and extract them into modules (in models dir) What''s left is a concise interface with some behaviours in declarative style (like acts_as_taxable). I''ve seen this working pretty well in largish 7 years old Rails application. Initially I haven''t appreciate such terse models until I came across some bloated ones. I then couldn''t quickly figure out what I can do with an instance of this model. Regards, Wojciech -- http://twitter.com/WojciechK On Dec 14, 6:00 pm, Jeff <cohen.j...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On Dec 14, 10:24 am, Andrew Edwards <and...-ZYDPpGlny4uS7RsuTa25KztV0T984lsv@public.gmane.org> > wrote: > > > Hi, > > > Given the convention of fat models to handle business logic, is there > > a point where you might be justified in using a separate plain ruby > > object(s) to orchestrate certain business logic interactions, > > essentially a middle layer between your controllers and models for > > high level functions? > > If you look at the InventoryTransaction model below you will see the > > sort of methods I mean. In this case they are similar to factory > > methods I suppose. However, I could end up with around 30+ different > > method handling different kinds of inventory adjustments. > > The idea is fat model *layer*, not necessarily fat model classes. You > should feel free to factor out inventory-handling methods into > separate Ruby modules or classes, and use them from within your > InventoryTransaction class. That way your ActiveRecord class isn''t > cluttered with lots of methods. I tend to keep such modules and pure- > Ruby classes in the models directory, but some people prefer to keep > them in lib/ instead. > > Jeff > > purpleworkshops.com-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Wojciech Kruszewski
2009-Dec-16 13:53 UTC
Re: Too many methods in the model? Extra lightweight logic layer?
P.S. Couple methods you listed seem good candidates to remain in model class. I suspect they are core of business logic and most important actions called in the controller. If there''s more than a dozen of them, I''d probably try to make them very short by extracting common parts into utility methods (and move them to another module). On Dec 15, 8:44 pm, Wojciech Kruszewski <wojci...-HCIsJdtRHLg@public.gmane.org> wrote:> I try to keep only high-level functionality and business logic in the > models. > > Here''s the drill: > > 1. identify things that are not specific to your model or application > and then extract them into a plugin > > 2. identify things that are specific to your application, but not to > your model and extract them into a lib > > 3. find groups of related methods that are lower level (used only in > this model itself) and extract them into modules (in models dir) > > What''s left is a concise interface with some behaviours in declarative > style (like acts_as_taxable). > > I''ve seen this working pretty well in largish 7 years old Rails > application. Initially I haven''t appreciate such terse models until I > came across some bloated ones. I then couldn''t quickly figure out what > I can do with an instance of this model. > > Regards, > Wojciech > > --http://twitter.com/WojciechK > > On Dec 14, 6:00 pm, Jeff <cohen.j...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > On Dec 14, 10:24 am, Andrew Edwards <and...-ZYDPpGlny4uS7RsuTa25KztV0T984lsv@public.gmane.org> > > wrote: > > > > Hi, > > > > Given the convention of fat models to handle business logic, is there > > > a point where you might be justified in using a separate plain ruby > > > object(s) to orchestrate certain business logic interactions, > > > essentially a middle layer between your controllers and models for > > > high level functions? > > > If you look at the InventoryTransaction model below you will see the > > > sort of methods I mean. In this case they are similar to factory > > > methods I suppose. However, I could end up with around 30+ different > > > method handling different kinds of inventory adjustments. > > > The idea is fat model *layer*, not necessarily fat model classes. You > > should feel free to factor out inventory-handling methods into > > separate Ruby modules or classes, and use them from within your > > InventoryTransaction class. That way your ActiveRecord class isn''t > > cluttered with lots of methods. I tend to keep such modules and pure- > > Ruby classes in the models directory, but some people prefer to keep > > them in lib/ instead. > > > Jeff > > > purpleworkshops.com-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.