I''m questioning what appears to be a recommendation that makes no sense in AWDWR 2nd Ed. I get the point being made, but the actual convention/implementation seems to make the point ineffective. If I have a controller Company with an action aboutus and an instance var of @contactInfo (a hash), and I have a view called aboutus.rhtml which renders a partial _contactus.rhtml, I could simply use the @contactInfo instance var inside _contactsus.rhtml. So, about doing that, AWDWR on page 125 says: -- In the layout, we have access to the @cart instance variable that was set by the controller. It turns out that this is also available inside partials called from the layout. However, this is a bit like calling a method and passing it some value in a global variable. It works, but its ugly coding, and it increases coupling (which in turn makes your programs brittle and hard to maintain). I think for many thing this likely isn''t necessary in practice for things that are obviously going to be coupled anyway, but I get it. A view might as well be abstracted the same way any method would be. At least you''d want that option. But here''s my problem... On page 510 the book says: -- Idiomatic Rails developers use a variable named after the template (article in this instance). In fact, its normal to take this a step further. If the object to be passed to the partial is in a controller instance variable with the same name as the partial, you can omit the :object parameter. OK, so what that says is if I have a controller Company with an action aboutus and an instance var of @contactInfo (a hash), and I have a view called aboutus.rhtml which renders a partial _contactInfo.rhtml (same name as the instance var this time), then the render command can simply be this: <%= render :partial => "contactInfo" %> Instead of having to write this: <%= render :partial => "contactInfo", :object => @contactInfo %> So now we have a partial using the code contactInfo[''phone''] instead of @contactInfo[''phone'']. If you ask me, the fact that we required the instace var to be named contactInfo, and the partial to be named contactInfo and then the local variable to be named contactInfo has created a higher degree of interdependence than if we just used the instance var directly in the partial. If I decide to change the instance var name in the controller, that is going to break the partial code in both cases. If I use the shortcut idiom and I changethe instance var, then I have to changethe name of the partial too. Where else might that break. But if I use the instance var directly in the partial, and changethe ivar name, then all I haveto do search & replace occurrences of that ivar name. Easy. fast, and fewer surprises as far as I can tell. So, what about this convention/idiom according to "the Daves" have I missed? -- gw -- Posted via http://www.ruby-forum.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-/JYPxA39Uh5TLH3MbocFFw@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 -~----------~----~----~----~------~----~------~--~---
> > On page 510 the book says: > > -- Idiomatic Rails developers use a variable named after the > template > (article in this instance). In fact, it’s normal to take this a step > further. If the object to be passed to the partial is in a controller > instance variable with the same name as the partial, you can omit the > :object parameter. > > OK, so what that says is if I have a controller Company with an action > aboutus and an instance var of @contactInfo (a hash), and I have a > view > called aboutus.rhtml which renders a partial _contactInfo.rhtml (same > name as the instance var this time), then the render command can > simply > be this: > > <%= render :partial => "contactInfo" %> > > Instead of having to write this: > > <%= render :partial => "contactInfo", :object => @contactInfo %>You don''t need to write that. you get that for free with <%= render :partial => "contactInfo" %> if @contactInfo exists. You only need it if you''re doing <%= render :partial => "contactInfo", :object => @someOthercontactInfo %>> > So now we have a partial using the code contactInfo[''phone''] > instead of > @contactInfo[''phone'']. > > If you ask me, the fact that we required the instace var to be named > contactInfo, and the partial to be named contactInfo and then the > local > variable to be named contactInfo has created a higher degree of > interdependence than if we just used the instance var directly in the > partial.-if you use the ivar in the partial and you change the ivar in the controller, you have to change the ivar everywhere. -if you don''t, but you use <%= render :partial => "contactInfo" %> and you change the ivar, you just have to add :object -if you don''t and you use <%= render :partial => "contactInfo", :object => @contactInfo %> then you just change the name there Change in one place vs change in 23 places But as far as I''m concerned that''s a relatively modest convenience. Using the ivar means that you can''t suddenly decide that you''d like to show a list of companies, since <%= render :partial => "contact_nfo", :collection => @contact_infos %> won''t work. It means that if that if you need to reuse that partial in some other place, eg a page where the ''natural'' instance variable is @company then you have to create @contact_info = @company.contact_info rather then <%= render :partial => "contactInfo", :object => @company.contact_info %> So yes, there''s a dependance between the name of the partial and the local variable that is materialised in that partial and there''s one between the name of the instance variable and the name of the partial that will just work magically with <%= render :partial => "contactInfo" %> but those 2 dependencies are separate. by using the ivar in the partial you tie both of those together and limit the reusability of that partial. Fred --~--~---------~--~----~------------~-------~--~----~ 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-/JYPxA39Uh5TLH3MbocFFw@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 -~----------~----~----~----~------~----~------~--~---
Frederick Cheung wrote:>> OK, so what that says is if I have a controller Company with an action >> >> <%= render :partial => "contactInfo", :object => @contactInfo %> > You don''t need to write that. you get that for free with <%> render :partial => "contactInfo" %> if @contactInfo exists. > You only need it if you''re doing > <%= render :partial => "contactInfo", :object => > @someOthercontactInfo %> >> partial. > -if you use the ivar in the partial and you change the ivar in the > controller, you have to change the ivar everywhere. > -if you don''t, but you use <%= render :partial => "contactInfo" %> > and you change the ivar, you just have to add :object > -if you don''t and you use <%= render :partial => > "contactInfo", :object => @contactInfo %> then you just change the > name there > Change in one place vs change in 23 places > > But as far as I''m concerned that''s a relatively modest convenience. > Using the ivar means that you can''t suddenly decide that you''d like > to show a list of companies, since <%= render :partial => > "contact_nfo", :collection => @contact_infos %> won''t work. It means > that if that if you need to reuse that partial in some other place, > eg a page where the ''natural'' instance variable is @company then you > have to create @contact_info = @company.contact_info rather then <%> render :partial => "contactInfo", :object => @company.contact_info %> > > So yes, there''s a dependance between the name of the partial and the > local variable that is materialised in that partial and there''s one > between the name of the instance variable and the name of the partial > that will just work magically with <%= render :partial => > "contactInfo" %> but those 2 dependencies are separate. by using the > ivar in the partial you tie both of those together and limit the > reusability of that partial.Thinking about it more, it seems to me the best version is to avoid the shortcut. The shortcut makes the ivar, the file name, and the local var in the partial all dependent on the same name. If I have two controllers sharing the use of a partial, and each controller & accompanying view for whatever reason have unique ivar names for the same data that could be passed to the partial, then the shortcut requires having two partials of unique names. Partials that draw generic lists comes to mind. If I declare :object in the render command, then whether I have two views, or I rename the ivar, the partial file name and internal local var remain undisturbed. Seems to me that this version does the best job at preserving the reusability of the partial from the standpoint of change in the controller and sharing among controllers. I have no trouble with the abstraction to broaden reuse potential, but that shortcut version of render seems to ruin it no matter how I look at it. So, it seems odd that it''s available. Its like someone found himself typing the same thing over & over in :object and decided a shortcut would be handy, but it turns out the shortcut ruins the very reusability goal that he started with. At least, itooks that way to me. Anyway, I did talk myself into at least using :object and not the ivar in the partial, but I also figure I''ll avoid "taking it further" with the shortcut. -- gw -- Posted via http://www.ruby-forum.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-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On 10/17/07, Greg Willits <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> > I''m questioning what appears to be a recommendation that makes no sense > in AWDWR 2nd Ed. I get the point being made, but the actual > convention/implementation seems to make the point ineffective. > > -- In the layout, we have access to the @cart instance variable that > was set by the controller. It turns out that this is also available > inside partials called from the layout. However, this is a bit like > calling a method and passing it some value in a global variable. It > works, but it''s ugly coding, and it increases coupling (which in turn > makes your programs brittle and hard to maintain).This is a good point. I don''t recommend using instance variables in partials. Everything should be passed to the partial from the template. Treat a partial like a subroutine that can be called in different contexts and that you pass arguments to.> On page 510 the book says: > > -- Idiomatic Rails developers use a variable named after the template > (article in this instance). In fact, it''s normal to take this a step > further. If the object to be passed to the partial is in a controller > instance variable with the same name as the partial, you can omit the > :object parameter.That may be an idiom, but it should be avoided IMO. It''s just a "shorthand" way of using global variables, which carries all the negative features of using global variables in general. Pass everything to partials. Don''t use instance vars in partials at all. --~--~---------~--~----~------------~-------~--~----~ 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-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Bob Showalter wrote:> On 10/17/07, Greg Willits <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote: >> makes your programs brittle and hard to maintain). > This is a good point. I don''t recommend using instance variables in > partials. Everything should be passed to the partial from the > template. Treat a partial like a subroutine that can be called in > different contexts and that you pass arguments to.So, one last question on this. If a partial requires multiple objects, is the preferred way to handle that by passing a hash of objects via :object? Something like this: render :partial => ''x'', :object => {''infoA'' => objectA, ''infoB'' => objectB} in which case I''d have a local var named x with a hash and could use x.infoA.someAttr -- gw -- Posted via http://www.ruby-forum.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-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On 10/17/07, Greg Willits <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> > Bob Showalter wrote: > > > On 10/17/07, Greg Willits <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote: > >> makes your programs brittle and hard to maintain). > > This is a good point. I don''t recommend using instance variables in > > partials. Everything should be passed to the partial from the > > template. Treat a partial like a subroutine that can be called in > > different contexts and that you pass arguments to. > > So, one last question on this. If a partial requires multiple objects, > is the preferred way to handle that by passing a hash of objects via > :object? Something like this: > > render :partial => ''x'', :object => {''infoA'' => objectA, ''infoB'' => > objectB} > > in which case I''d have a local var named x with a hash and could use > x.infoA.someAttrYou can do that, but it would be x[''infoA''].someAttr Preferred is to pass multiple values using :locals render :partial => ''x'', :locals => {:infoA => objectA, :infoB => objectB} Then in the partial, you have reference separate variables: infoA.someAttr infoB.someAttr --~--~---------~--~----~------------~-------~--~----~ 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-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Bob Showalter wrote:> On 10/17/07, Greg Willits <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote: >> So, one last question on this. If a partial requires multiple objects, >> is the preferred way to handle that by passing a hash of objects via >> :object? Something like this: >> >> render :partial => ''x'', :object => {''infoA'' => objectA, ''infoB'' => >> objectB} >> >> in which case I''d have a local var named x with a hash and could use >> x.infoA.someAttr > > You can do that, but it would be > > x[''infoA''].someAttrduh, I knew that :-P> Preferred is to pass multiple values using :locals > > render :partial => ''x'', :locals => {:infoA => objectA, :infoB => > objectB} > > Then in the partial, you have reference separate variables: > > infoA.someAttr > infoB.someAttrPerfect, that''s _much_ better. I think I like that even better for a single object. Using the partial name as the local var bothered me. I get it, but wasn''t fond of it. I''d much rather have the var name represent what the object is. Thx. -- gw -- Posted via http://www.ruby-forum.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-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
May I use :collection and :locals together to handle parameters while rendering partial? Thanks! On 10月18日, 上午4时57分, "Bob Showalter" <showa...@gmail.com> wrote:> On 10/17/07, Greg Willits <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote: > > > > > > > Bob Showalter wrote: > > > > On 10/17/07, Greg Willits <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote: > > >> makes your programs brittle and hard to maintain). > > > This is a good point. I don''t recommend usinginstancevariables in > > > partials. Everything should be passed to the partial from the > > > template. Treat a partial like a subroutine that can be called in > > > different contexts and that you pass arguments to. > > > So, one last question on this. If a partial requires multiple objects, > > is the preferred way to handle that by passing a hash of objects via > > :object? Something like this: > > > render :partial => ''x'', :object=> {''infoA'' => objectA, ''infoB'' => > > objectB} > > > in which case I''d have a local var named x with a hash and could use > > x.infoA.someAttr > > You can do that, but it would be > > x[''infoA''].someAttr > > Preferred is to pass multiple values using :locals > > render :partial => ''x'', :locals => {:infoA => objectA, :infoB => objectB} > > Then in the partial, you have reference separate variables: > > infoA.someAttr > infoB.someAttr--~--~---------~--~----~------------~-------~--~----~ 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-/JYPxA39Uh5TLH3MbocFFw@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 -~----------~----~----~----~------~----~------~--~---
On Nov 6, 2007 9:10 PM, eastwoodsz <robbinwooo-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > May I use :collection and :locals together to handle parameters while > rendering partial?Yes. --~--~---------~--~----~------------~-------~--~----~ 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-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---