← Back to Upcase

Best practice: Don't use instance variables in partials


(Justin Gordon) #1

From https://github.com/thoughtbot/guides/tree/master/best-practices

Don’t use instance variables in partials. Pass local variables to partials from view templates.

I’d like to clarify if this implies that local variable definitions are OK in haml. Or if they should be avoid. I’ve also been trying to using page objects can avoid conditionals in the haml, but those also seem impossible to totally avoid.

I’ve got this haml code which needs to do something with the first value from the association. Should this be done any differently?

    .row
      .col-sm-12
        - first = obj.my_children.first
        .class-for-first
          = first.some_value
        - first = true
        .class-for-rest
          %ul
            - obj.my_children.each do |child|
              - if first
                - first = false
              -else
                %li
                  = child.some_value

(Geoff Harcourt) #2

@Justin_Gordon, that tip is not actually referencing what you’re doing here. Instance variables in this case are the @variable items that are created in controllers and passed on to the view. Sometimes folks will rely on these instance variables being effectively global and rely on them existing in partials without passing them on in the call to render the partial.

Instead of rendering the partial like this (having set @object in the controller):
= render 'object'

You should render it like this:

= render 'object', object: @object

I have found that relying on the global aspect of instance variables is bad practice for the most part because it cramps future reusability. If another controller refers to that concept with a different name, you can’t just reuse the code.

BTW, I think for the scenario you’ve laid out, rather than implement all that messy inline variable declaration and the if/else branch, I would just set a CSS rule for the :first-child for your list that gives it a different appearance than the others, then you can just iterate through the items (maybe give the ul a class to help define your CSS rules) and a much cleaner Haml template.