Giter Club home page Giter Club logo

Comments (4)

ajb avatar ajb commented on September 3, 2024

Alright, I spoke too soon. Here's the key detail: the view class name was the same as the needs key. I'll edit the example above accordingly.

from fortitude.

ajb avatar ajb commented on September 3, 2024

Here's a relevant commit from erector-rails4: https://github.com/ajb/erector-rails4/commit/961916cfb372f6ff6b8d0493aa29c6b3bfe28c9f

from fortitude.

ageweke avatar ageweke commented on September 3, 2024

I think what you need is this:

implicit_shared_variable_access true

extra_assigns :use says to Fortitude: if a widget is explicitly passed data (or, at the very top level, any instance variables set by the Rails controller) beyond the scope of its needs, use that, too. However, that still has to be data explicitly passed to it. In the case of Views::Components::Project, that isn’t true, because the render call passes no locals — which are what get turned into Fortitude needs when you use render. (Using widget Views::Components::Project is considerably faster than render, FWIW, not that it makes a big difference unless you call it a zillion times. It also obviously makes the parameter passing more clear.) If you changed it to render 'components/project', :locals => { :project => @project }, then it’d work — but you also wouldn’t need the needs :project, since extra_assigns :use obviates that.

implicit_shared_variable_access true says to Fortitude: let all widgets, anywhere in the hierarchy, access controller instance variables as if they were needs. This is what makes it behave the most like ERb and Erector.

FWIW, the reason these aren’t the defaults is as follows: I worked on a very large Rails codebase for several years at one of the top Rails sites in the world. The view hierarchy had gradually grown enormous, and kind of insane. At one point, we discovered that if you moved one render :partial call before another render :partial call on the page, the first one (now second one) would break. What? We eventually discovered that one partial was actually setting an instance variable (@foo = …) that the other one was reading (@foo).

On one hand, yeah, that’s a moronic thing to do and whoever wrote that code should be smacked. On the other, man, there’s a reason languages don’t let you do that in general — global variables are bad, mmmmkay? Yet, in the ERb model of the world, everything is a global variable to all views and partials in the entire system. That seems crazy to me. Fortitude’s model is, by default, almost identical to traditional named-parameter-passing: a method (widget) has access only to the data passed to it (its needs), and nothing more. Want more data? Pass it in. This makes widgets vastly easier to reason about at scale, IMHO, and a whole lot cleaner.

(BTW, this is also why, by default, use_instance_variables_for_assigns is false, and you’d access @project in method-style, instead, as project. Why is that better? Because if you misspell it — or, more likely, don’t fully complete a name change — as @prjoect, you just get nil and quite possibly no data being rendered in a confusing way; if you misspell it as prjoect, you get a clear error.)

Having said that, implicit_shared_variable_access is there exactly because I know some people want the old, ERb-style model anyway, and, if you do, have at it!

Finally, the weird name thing comes from this. Rails has the following behavior: you can say render :partial => 'project', :object => @my_project, and then you can access that data inside the project partial as just @project. It really comes from rendering collections, where you can say render :partial => 'project', :collection => @my_projects, and get one instance of the partial for each element of the array @my_projects. In such a case, Rails has no clear name for the actual data passed in, and so it calls it by the name of the partial itself — @project. Fortitude supports this, too, same as ERb and Erector.

Let me know if you run into any other issues here, but, AFAICT, it works as designed — just needs better docs (which I'm working on)!

from fortitude.

ajb avatar ajb commented on September 3, 2024

Thanks for the help! render object: @project is the missing piece that I didn't know about. 👍 on everything else :)

from fortitude.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.