I am quite certain I have heard it said not to put business logic inside view code but I have a report that I want to display 3 different possibilities of text based upon the value of a column. Would I just take the same type of if/then logic that I would use in a controller and put it inside erb <%= %> stuff? Craig
No! Use a helper instead. -- -- Tom Mornini On Mar 20, 2006, at 1:29 PM, Craig White wrote:> I am quite certain I have heard it said not to put business logic > inside > view code but I have a report that I want to display 3 different > possibilities of text based upon the value of a column. Would I just > take the same type of if/then logic that I would use in a > controller and > put it inside erb <%= %> stuff? > > Craig > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails
On 3/20/06, Craig White <craigwhite@azapple.com> wrote:> I am quite certain I have heard it said not to put business logic inside > view code but I have a report that I want to display 3 different > possibilities of text based upon the value of a column. Would I just > take the same type of if/then logic that I would use in a controller and > put it inside erb <%= %> stuff?For the Rails projects I''ve seen and managed, it seems that the line between ''controller'' and ''view'' code is this: querying the database or modifying variables is only done in controllers. Beyond that, any logic for modifying the page is fair game for your view. Of course, this is only my opinion, and there is nothing stopping you (outside method availability) from putting any sort of code you want in your views. Over time you will get a better idea of when some code will become difficult to maintain. As a rule of thumb, if you find yourself putting the same code in multiple places, you''ll probably want to abstract that using partials, helpers, controller parent classes, or something else. Good luck with your decisions.> CraigSincerely, Tom Lieber http://AllTom.com/ http://GadgetLife.org/
On Mon, 2006-03-20 at 16:46 -0500, Tom Lieber wrote:> On 3/20/06, Craig White <craigwhite@azapple.com> wrote: > > I am quite certain I have heard it said not to put business logic inside > > view code but I have a report that I want to display 3 different > > possibilities of text based upon the value of a column. Would I just > > take the same type of if/then logic that I would use in a controller and > > put it inside erb <%= %> stuff? > > For the Rails projects I''ve seen and managed, it seems that the line > between ''controller'' and ''view'' code is this: querying the database or > modifying variables is only done in controllers. Beyond that, any > logic for modifying the page is fair game for your view. Of course, > this is only my opinion, and there is nothing stopping you (outside > method availability) from putting any sort of code you want in your > views. > > Over time you will get a better idea of when some code will become > difficult to maintain. As a rule of thumb, if you find yourself > putting the same code in multiple places, you''ll probably want to > abstract that using partials, helpers, controller parent classes, or > something else. > > Good luck with your decisions. > > > Craig > > Sincerely, > > Tom Lieber---- On Mon, 2006-03-20 at 13:40 -0800, Tom Mornini wrote:> No! > > Use a helper instead. >---- Two Tom''s, two entirely different answers. ;-) thanks...I pretty much made my decision for now as it''s a simple task (or it seems to me to be a simple task), to just insert the quickie into the view code - especially since it only evaluates values from an existing hash. Craig
Good decision. We need to stop feeling guilty about putting conditionals in views just because its the same thing we did in ASP & PHP. Ruby is a good language for making simple conditional statements, what difference does it make if its eRuby? Tom''s advice is good imho. If you want to really insulate the view maybe look at Liquid templates but be sure you know why you are doing - "the architect says" is not really a reason. On 3/20/06, Craig White <craigwhite@azapple.com> wrote:> On Mon, 2006-03-20 at 16:46 -0500, Tom Lieber wrote: > > On 3/20/06, Craig White <craigwhite@azapple.com> wrote: > > > I am quite certain I have heard it said not to put business logic inside > > > view code but I have a report that I want to display 3 different > > > possibilities of text based upon the value of a column. Would I just > > > take the same type of if/then logic that I would use in a controller and > > > put it inside erb <%= %> stuff? > > > > For the Rails projects I''ve seen and managed, it seems that the line > > between ''controller'' and ''view'' code is this: querying the database or > > modifying variables is only done in controllers. Beyond that, any > > logic for modifying the page is fair game for your view. Of course, > > this is only my opinion, and there is nothing stopping you (outside > > method availability) from putting any sort of code you want in your > > views. > > > > Over time you will get a better idea of when some code will become > > difficult to maintain. As a rule of thumb, if you find yourself > > putting the same code in multiple places, you''ll probably want to > > abstract that using partials, helpers, controller parent classes, or > > something else. > > > > Good luck with your decisions. > > > > > Craig > > > > Sincerely, > > > > Tom Lieber > ---- > On Mon, 2006-03-20 at 13:40 -0800, Tom Mornini wrote: > > > No! > > > > Use a helper instead. > > > ---- > Two Tom''s, two entirely different answers. > > ;-) > > thanks...I pretty much made my decision for now as it''s a simple task (or it seems to me to be a simple task), to just insert the quickie into the view code - especially since it only evaluates values from an existing hash. > > Craig > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- Jeremy Huffman http://www.jeremyhuffman.com
On Mon, 2006-03-20 at 21:59 -0500, Jeremy Huffman wrote:> Good decision. We need to stop feeling guilty about putting > conditionals in views just because its the same thing we did in ASP & > PHP. Ruby is a good language for making simple conditional statements, > what difference does it make if its eRuby? Tom''s advice is good imho. > If you want to really insulate the view maybe look at Liquid templates > but be sure you know why you are doing - "the architect says" is not > really a reason.---- I did - it''s done, it works, it''s ugly ;-) <%= (facility.pltype == "PAH" ? " PAH (11:59 PM) " : (facility.pltype == "16 Hour" ? " 16 Hour (11:59 PM) " : " Bed Check (11:59 PM) ")) %> I didn''t indent it with the rest of the html code to make it stand out like the proverbial sore thumb. Simple, effective ugly...like I like my women ;-) just kidding Craig
Craig White wrote:> <%= (facility.pltype == "PAH" ? " PAH (11:59 PM) " : > (facility.pltype == "16 Hour" ? " 16 Hour (11:59 PM) " : > " Bed Check (11:59 PM) ")) %>There is common text between those three cases: you could move it out of the dynamic expression: <%= ... %> (11:59 PM) What is the value of facility.pltype when you want "Bed Check" to be displayed? It would be nice if it was just "Bed Check": <%= facility.pltype %> (11:59 PM) A helper method is valuable (a) to take logic out of the view, and (b) to allow the logic to be re-used in different views, without duplication. E.g. In application_helper.rb (or whatever more specific helper is appropriate): def display_pltype(pltype) pltype == "PAH" || pltype == "16 Hour" ? pltype : "Bed Check" end In template: <%= display_pltype(facility.pltype) %> (11:59 PM) ...Rails lets you keep your views clean with very little extra work (and it should pay back in terms of maintainability) It''s your choice! Justin
On Tue, 2006-03-21 at 04:05 +0000, Justin Forder wrote:> Craig White wrote: > > > <%= (facility.pltype == "PAH" ? " PAH (11:59 PM) " : > > (facility.pltype == "16 Hour" ? " 16 Hour (11:59 PM) " : > > " Bed Check (11:59 PM) ")) %> > > There is common text between those three cases: you could move it out of > the dynamic expression: > > <%= ... %> (11:59 PM) > > What is the value of facility.pltype when you want "Bed Check" to be > displayed? It would be nice if it was just "Bed Check": > > <%= facility.pltype %> (11:59 PM) ---- yeah but it isn''t. There are a number of other pltypes...it''s just those particular 2 don''t perform bed checks. ----> > A helper method is valuable (a) to take logic out of the view, and (b) > to allow the logic to be re-used in different views, without duplication. > > E.g. > > In application_helper.rb (or whatever more specific helper is appropriate): > > def display_pltype(pltype) > pltype == "PAH" || pltype == "16 Hour" ? pltype : "Bed Check" > end > > In template: > > <%= display_pltype(facility.pltype) %> (11:59 PM) > > ...Rails lets you keep your views clean with very little extra work (and > it should pay back in terms of maintainability) > > It''s your choice!---- Thanks for taking the time to explain that. I am somewhat new to all this and that is very imaginative and I think I understand it and will likely change to using it. The next phase is to clean up all of the sloppy code that I did to get this far...as I have seen that using some of these types of ruby snippets are really effective and I''ve got a lot of ''WET'' ( WET != DRY ) type code in my controllers but I didn''t want to get bogged down with the higher quality usage of things I wasn''t on top of - especially when I started with this 6 weeks ago (the first two controllers/models that I did are probably dripping WET). I presume if I just put this into my facility class...I could just simply refer to in my template with <% Facility.display_pltype(facility.pltype) %> and while it is more typing than your suggestion, it does keep things in it''s place. I guess the thing I don''t understand is...why would this go into a model or a helper? What is the criteria? (other than arbitrary)...btw, this code runs from my ''reports'' controller. Thanks again Craig
Craig White wrote:> On Tue, 2006-03-21 at 04:05 +0000, Justin Forder wrote: >> Craig White wrote: >> >>> <%= (facility.pltype == "PAH" ? " PAH (11:59 PM) " : >>> (facility.pltype == "16 Hour" ? " 16 Hour (11:59 PM) " : >>> " Bed Check (11:59 PM) ")) %> >> There is common text between those three cases: you could move it out of >> the dynamic expression: >> >> <%= ... %> (11:59 PM) >> >> What is the value of facility.pltype when you want "Bed Check" to be >> displayed? It would be nice if it was just "Bed Check": >> >> <%= facility.pltype %> (11:59 PM) > ---- > yeah but it isn''t. There are a number of other pltypes...it''s just those > particular 2 don''t perform bed checks.OK. My helper, below, didn''t make that assumption.> ---- >> A helper method is valuable (a) to take logic out of the view, and (b) >> to allow the logic to be re-used in different views, without duplication. >> >> E.g. >> >> In application_helper.rb (or whatever more specific helper is appropriate): >> >> def display_pltype(pltype) >> pltype == "PAH" || pltype == "16 Hour" ? pltype : "Bed Check" >> end >> >> In template: >> >> <%= display_pltype(facility.pltype) %> (11:59 PM) >> >> ...Rails lets you keep your views clean with very little extra work (and >> it should pay back in terms of maintainability) >> >> It''s your choice! > ---- > Thanks for taking the time to explain that. I am somewhat new to all > this and that is very imaginative and I think I understand it and will > likely change to using it. > > The next phase is to clean up all of the sloppy code that I did to get > this far...as I have seen that using some of these types of ruby > snippets are really effective and I''ve got a lot of ''WET'' ( WET != DRY ) > type code in my controllers but I didn''t want to get bogged down with > the higher quality usage of things I wasn''t on top of - especially when > I started with this 6 weeks ago (the first two controllers/models that I > did are probably dripping WET).Fine. Don''t leave it too long - the WET stuff is probably already slowing you down, and it''s good to get into the habit of refactoring as you go, rather than saving it up for a quieter time (which may never happen).> I presume if I just put this into my facility class...I could just > simply refer to in my template with > <% Facility.display_pltype(facility.pltype) %> > > and while it is more typing than your suggestion, it does keep things in > it''s place.Indeed. Less typing if you make it an instance method of Facility: def display_pltype pltype == "PAH" || pltype == "16 Hour" ? pltype : "Bed Check" end <%= facility.display_pltype %> ...but this raises the question you ask below:> > I guess the thing I don''t understand is...why would this go into a model > or a helper? What is the criteria? (other than arbitrary)...btw, this > code runs from my ''reports'' controller.OK, so if you use a helper method it would probably go in your reports_helper. It is a matter of judgement - is this really business logic, or does it relate to how you present the underlying model. It appears to me that it may be a bit of both. Sorry not to reply in more detail - have to go to work! regards Justin
On Tue, 2006-03-21 at 07:50 +0000, Justin Forder wrote:> Craig White wrote:> >> What is the value of facility.pltype when you want "Bed Check" to be > >> displayed? It would be nice if it was just "Bed Check": > >> > >> <%= facility.pltype %> (11:59 PM) > > ---- > > yeah but it isn''t. There are a number of other pltypes...it''s just those > > particular 2 don''t perform bed checks. > > OK. My helper, below, didn''t make that assumption.---- I did notice - that''s why it was so obvious to me that I should probably incorporate it. ----> > > ---- > >> A helper method is valuable (a) to take logic out of the view, and (b) > >> to allow the logic to be re-used in different views, without duplication. > >> > >> E.g. > >> > >> In application_helper.rb (or whatever more specific helper is appropriate): > >> > >> def display_pltype(pltype) > >> pltype == "PAH" || pltype == "16 Hour" ? pltype : "Bed Check" > >> end > >> > >> In template: > >> > >> <%= display_pltype(facility.pltype) %> (11:59 PM) > >> > >> ...Rails lets you keep your views clean with very little extra work (and > >> it should pay back in terms of maintainability) > >> > >> It''s your choice! > > ---- > > Thanks for taking the time to explain that. I am somewhat new to all > > this and that is very imaginative and I think I understand it and will > > likely change to using it. > > > > The next phase is to clean up all of the sloppy code that I did to get > > this far...as I have seen that using some of these types of ruby > > snippets are really effective and I''ve got a lot of ''WET'' ( WET != DRY ) > > type code in my controllers but I didn''t want to get bogged down with > > the higher quality usage of things I wasn''t on top of - especially when > > I started with this 6 weeks ago (the first two controllers/models that I > > did are probably dripping WET). > > Fine. Don''t leave it too long - the WET stuff is probably already > slowing you down, and it''s good to get into the habit of refactoring as > you go, rather than saving it up for a quieter time (which may never > happen).---- well - I feel as though I should defend myself...I have taken this from 0 to a fairly well defined application in 6 weeks and it is my first project but clearly, what I knew 6 weeks ago was decidedly less than 4 weeks ago, two weeks ago and obviously today. The first task was getting it done - regardless of all the things I didn''t understand at the time...I assumed that I would catch on along the way and I sort of catching on. I am quite sure that there is stuff slowing me down...like my stupidity tonight with svn and deleting a folder that I wanted to keep. But the code seriously needs cleanup and that is a big priority after I propogate the current branch because this branch has all of the reports needed for them to fully replace the other methodology that this rails application is replacing. ----> > > I presume if I just put this into my facility class...I could just > > simply refer to in my template with > > <% Facility.display_pltype(facility.pltype) %> > > > > and while it is more typing than your suggestion, it does keep things in > > it''s place. > > Indeed. Less typing if you make it an instance method of Facility: > > def display_pltype > pltype == "PAH" || pltype == "16 Hour" ? pltype : "Bed Check" > end > > <%= facility.display_pltype %> > > ...but this raises the question you ask below:---- well - I should state that I was a little afraid of using ''facility.display_pltype'' directly since we are directly within an iteration with a hash named ''facility'' and this could be a bit confusing. To me...it''s a method defined within the facility but I haven''t found a reason to put stuff in helpers yet. ----> > > > I guess the thing I don''t understand is...why would this go into a model > > or a helper? What is the criteria? (other than arbitrary)...btw, this > > code runs from my ''reports'' controller. > > OK, so if you use a helper method it would probably go in your > reports_helper. > > It is a matter of judgement - is this really business logic, or does it > relate to how you present the underlying model. It appears to me that it > may be a bit of both. > > Sorry not to reply in more detail - have to go to work!---- Thanks for your excellent illustrations for me. I do appreciate it. Craig
Craig White wrote:> I guess the thing I don''t understand is...why would this go into a > model > or a helper? What is the criteria? (other than arbitrary)...btw, this > code runs from my ''reports'' controller.my 2 cents: It belongs in a model if: 1) It can provide data to other code in a way that will not change if the underlying representation changes. Other code should never have intimate knowledge of underlying representation. It belongs in a helper if: 1) It needs to be shared amongst more than 1 controller (authorization and authentication comes to mind) 2) It relates to view code As an example: Imagine we have a model that has a column, :type, and that column can contain ''M'', ''C'', or ''A'', which represent MasterCard, Visa, and Amex, respectively. Nothing outside the model should *ever* know about ''M'', ''C'', and ''A''! Instead, in the model: def is_mastercard? type == ''M'' end def is_visa? type == ''V'' end def is_amex? type == ''A'' end And a helper: def card_name_for(card) return "MasterCard" if card.is_mastercard? return "Visa" if card.is_visa? return "Priceless :-)" if card.is_amex? end And in the view: <% for card in @cards -%> Type: <%= card_name_for(card) %> <% end -%> This gives you a great deal of isolation, and some useful methods on the model that make the helper and (no doubt) other code more readable, and allows for a complete refactor of Card.type in the future without changing anything else. For instance, why store card type at all when it can be derived from the card number itself? If you''ve written it this way, you can drop the column, add the card number differentiation logic to the is_*? model methods, and you''re done. -- -- Tom Mornini
On Tue, 2006-03-21 at 00:30 -0800, Tom Mornini wrote:> Craig White wrote: > > > I guess the thing I don''t understand is...why would this go into a > > model > > or a helper? What is the criteria? (other than arbitrary)...btw, this > > code runs from my ''reports'' controller. > > my 2 cents: > > It belongs in a model if: > > 1) It can provide data to other code in a way that will not change if > the underlying representation changes. Other code should never > have > intimate knowledge of underlying representation. > > It belongs in a helper if: > > 1) It needs to be shared amongst more than 1 controller > (authorization > and authentication comes to mind) > 2) It relates to view code > > As an example: Imagine we have a model that has a column, :type, and > that > column can contain ''M'', ''C'', or ''A'', which represent MasterCard, > Visa, and > Amex, respectively. > > Nothing outside the model should *ever* know about ''M'', ''C'', and ''A''! > > Instead, in the model: > > def is_mastercard? > type == ''M'' > end > > def is_visa? > type == ''V'' > end > > def is_amex? > type == ''A'' > end > > And a helper: > > def card_name_for(card) > return "MasterCard" if card.is_mastercard? > return "Visa" if card.is_visa? > return "Priceless :-)" if card.is_amex? > end > > And in the view: > > <% for card in @cards -%> > Type: <%= card_name_for(card) %> > <% end -%> > > This gives you a great deal of isolation, and some useful > methods on the model that make the helper and (no doubt) > other code more readable, and allows for a complete > refactor of Card.type in the future without changing > anything else. > > For instance, why store card type at all when it can be > derived from the card number itself? If you''ve written it > this way, you can drop the column, add the card number > differentiation logic to the is_*? model methods, and you''re > done.--- makes sense to me - thanks - y''all are learnin'' me good ;-) Craig
Tom Mornini wrote:> Craig White wrote: > >> I guess the thing I don''t understand is...why would this go into a model >> or a helper? What is the criteria? (other than arbitrary)...btw, this >> code runs from my ''reports'' controller. > > my 2 cents: > > It belongs in a model if: > > 1) It can provide data to other code in a way that will not change if > the underlying representation changes. Other code should never have > intimate knowledge of underlying representation. > > It belongs in a helper if: > > 1) It needs to be shared amongst more than 1 controller (authorization > and authentication comes to mind) > 2) It relates to view code > > As an example: Imagine we have a model that has a column, :type, and that > column can contain ''M'', ''C'', or ''A'', which represent MasterCard, Visa, and > Amex, respectively. > > Nothing outside the model should *ever* know about ''M'', ''C'', and ''A''! > > Instead, in the model: > > def is_mastercard? > type == ''M'' > end > > def is_visa? > type == ''V'' > end > > def is_amex? > type == ''A'' > end > > And a helper: > > def card_name_for(card) > return "MasterCard" if card.is_mastercard? > return "Visa" if card.is_visa? > return "Priceless :-)" if card.is_amex? > end > > And in the view: > > <% for card in @cards -%> > Type: <%= card_name_for(card) %> > <% end -%> > > This gives you a great deal of isolation, and some useful > methods on the model that make the helper and (no doubt) > other code more readable, and allows for a complete > refactor of Card.type in the future without changing > anything else. > > For instance, why store card type at all when it can be > derived from the card number itself? If you''ve written it > this way, you can drop the column, add the card number > differentiation logic to the is_*? model methods, and you''re > done.Excellent example. Coming back to Craig''s implementation: - pltype field values are not abstracted away from the presented form (e.g. "16 Hour") - the business logic corresponding to Craig''s statement that "There are a number of other pltypes...it''s just those particular 2 ["PAH", "16 Hour"] don''t perform bed checks." is not implemented in the model, but is left to be implemented in the view. So I think my most pressing question would be "Can you put a name to the thing that is being displayed as either ''PAH'', ''16 Hour'', or ''Bed Check''?" To put that another way, if this was being displayed in label: value format, what would the label be? I''m sure it wouldn''t be ''display_pltype''! The answer to that question would tell us how to name a new method on the model. regards Justin
Craig White wrote:> On Tue, 2006-03-21 at 07:50 +0000, Justin Forder wrote: >> Craig White wrote:>>> The next phase is to clean up all of the sloppy code that I did to get >>> this far...as I have seen that using some of these types of ruby >>> snippets are really effective and I''ve got a lot of ''WET'' ( WET != DRY ) >>> type code in my controllers but I didn''t want to get bogged down with >>> the higher quality usage of things I wasn''t on top of - especially when >>> I started with this 6 weeks ago (the first two controllers/models that I >>> did are probably dripping WET).>> Fine. Don''t leave it too long - the WET stuff is probably already >> slowing you down, and it''s good to get into the habit of refactoring as >> you go, rather than saving it up for a quieter time (which may never >> happen). > ---- > well - I feel as though I should defend myself...I have taken this from > 0 to a fairly well defined application in 6 weeks and it is my first > project but clearly, what I knew 6 weeks ago was decidedly less than 4 > weeks ago, two weeks ago and obviously today. The first task was getting > it done - regardless of all the things I didn''t understand at the > time...I assumed that I would catch on along the way and I sort of > catching on.I didn''t mean to sound critical - sorry if it came over that way.>>> I presume if I just put this into my facility class...I could just >>> simply refer to in my template with >>> <% Facility.display_pltype(facility.pltype) %> >>> >>> and while it is more typing than your suggestion, it does keep things in >>> it''s place. >> Indeed. Less typing if you make it an instance method of Facility: >> >> def display_pltype >> pltype == "PAH" || pltype == "16 Hour" ? pltype : "Bed Check" >> end >> >> <%= facility.display_pltype %> >> >> ...but this raises the question you ask below: > ---- > well - I should state that I was a little afraid of using > ''facility.display_pltype'' directly since we are directly within an > iteration with a hash named ''facility'' and this could be a bit > confusing.OK. If facility is a hash, then you would need to get the pltype using facility[''pltype''] (or facility[:pltype], if you prefer to use symbols for hash keys). This is a good illustration of how you gain flexibility by having your view work directly against your models, rather than pulling the information out of the models into hashes and giving those to the views. (By the way, what does ''pltype'' stand for?) regards Justin
On Wed, 2006-03-22 at 00:40 +0000, Justin Forder wrote:> >>> I presume if I just put this into my facility class...I could just > >>> simply refer to in my template with > >>> <% Facility.display_pltype(facility.pltype) %> > >>> > >>> and while it is more typing than your suggestion, it does keep things in > >>> it''s place. > >> Indeed. Less typing if you make it an instance method of Facility: > >> > >> def display_pltype > >> pltype == "PAH" || pltype == "16 Hour" ? pltype : "Bed Check" > >> end > >> > >> <%= facility.display_pltype %> > >> > >> ...but this raises the question you ask below: > > ---- > > well - I should state that I was a little afraid of using > > ''facility.display_pltype'' directly since we are directly within an > > iteration with a hash named ''facility'' and this could be a bit > > confusing. > > OK. If facility is a hash, then you would need to get the pltype using > facility[''pltype''] (or facility[:pltype], if you prefer to use symbols > for hash keys). > > This is a good illustration of how you gain flexibility by having your > view work directly against your models, rather than pulling the > information out of the models into hashes and giving those to the views. > > (By the way, what does ''pltype'' stand for?)---- pltype has sort of morphed. The ''type'' originally started in the placement as it was inadequately described to me as being a property of the placement - turns out, it is not really a property of the placement but of the facility. ''pltype'' stood for the type of program - this is a place for partially and SMI''s and the programs would be like ''PAH/Asissted Housing, or 24 Hour, etc. The ''pl'' came from the misunderstanding that I had thinking it related to the ''placement'' and ''type'' is really the better term but as I came to discover, it was a reserved word. So the whole nature of ''pltype'' has roots in issues ;-) Basically, it is about the type of care level that is provided. Thanks Craig
On Wed, 2006-03-22 at 00:28 +0000, Justin Forder wrote:> Tom Mornini wrote: > > Craig White wrote: > > > >> I guess the thing I don''t understand is...why would this go into a model > >> or a helper? What is the criteria? (other than arbitrary)...btw, this > >> code runs from my ''reports'' controller. > > > > my 2 cents: > > > > It belongs in a model if: > > > > 1) It can provide data to other code in a way that will not change if > > the underlying representation changes. Other code should never have > > intimate knowledge of underlying representation. > > > > It belongs in a helper if: > > > > 1) It needs to be shared amongst more than 1 controller (authorization > > and authentication comes to mind) > > 2) It relates to view code > > > > As an example: Imagine we have a model that has a column, :type, and that > > column can contain ''M'', ''C'', or ''A'', which represent MasterCard, Visa, and > > Amex, respectively. > > > > Nothing outside the model should *ever* know about ''M'', ''C'', and ''A''! > > > > Instead, in the model: > > > > def is_mastercard? > > type == ''M'' > > end > > > > def is_visa? > > type == ''V'' > > end > > > > def is_amex? > > type == ''A'' > > end > > > > And a helper: > > > > def card_name_for(card) > > return "MasterCard" if card.is_mastercard? > > return "Visa" if card.is_visa? > > return "Priceless :-)" if card.is_amex? > > end > > > > And in the view: > > > > <% for card in @cards -%> > > Type: <%= card_name_for(card) %> > > <% end -%> > > > > This gives you a great deal of isolation, and some useful > > methods on the model that make the helper and (no doubt) > > other code more readable, and allows for a complete > > refactor of Card.type in the future without changing > > anything else. > > > > For instance, why store card type at all when it can be > > derived from the card number itself? If you''ve written it > > this way, you can drop the column, add the card number > > differentiation logic to the is_*? model methods, and you''re > > done. > > Excellent example. > > Coming back to Craig''s implementation: > > - pltype field values are not abstracted away from the > presented form (e.g. "16 Hour") > > - the business logic corresponding to Craig''s statement that > > "There are a number of other pltypes...it''s just those > particular 2 ["PAH", "16 Hour"] don''t perform bed checks." > > is not implemented in the model, but is left to be implemented > in the view. > > So I think my most pressing question would be "Can you put a name to the > thing that is being displayed as either ''PAH'', ''16 Hour'', or ''Bed Check''?" > > To put that another way, if this was being displayed in label: value > format, what would the label be? I''m sure it wouldn''t be ''display_pltype''! > > The answer to that question would tell us how to name a new method on > the model.---- I think it is borderline but whether it gets any usage beyond this one form would strike me as the reason to put it into a model or just leave it in the view. The ''pltype'' is for categorization for the governmental agencies whereas the form itself, is simply a ''worksheet'' for the staff to report the daily log. Thus the point is the ''assisted living'' type clients wouldn''t get a bed check and they don''t want the implication on the form itself that a bed check is expected or proper for that particular facility. Craig
On 3/20/06, Craig White <craigwhite@azapple.com> wrote:> I am quite certain I have heard it said not to put business logic inside > view code but I have a report that I want to display 3 different > possibilities of text based upon the value of a column. Would I just > take the same type of if/then logic that I would use in a controller and > put it inside erb <%= %> stuff?So far I have been generally able to limit view templates to if-else and iterating over collections occasionally with each(). The latter can of course often be awesomely addressed using render() with the :collection option. It''s sensible if you''re going to bother with MVC to really strive to keep your templates as dumb as possible, it seems. Things are much more pleasant to deal with. Exceptions always occur, though, so use your best judgement. :) -- Seth Thomas Rasmussen http://sethrasmussen.com/