I'm trying to build a Rails view with multiple components that use separate controllers, similar to how a Vue or React app has components with different data sources on the same page.
I've looked closely at rails partials and ViewCompoents (https://viewcomponent.org/), but nether seems suitable.
I'll use a book publishing website on the books.com/index page as an example.
header and body come from the layout.
blue block on the left is a "list of publishers" using the publisher's controller.
pink block on the right is a "list of books" using the books controller.
I'm still junior Rails dev so please don't flame me if this is an obvious question, but I can't find any examples of how to do this. Maybe my understanding of a controller is flawed because I'm used to thinking about 1 controller with 1 model...
Any help or links to resources would be appreciated!
I think what you're looking for here is Turbo Frames. If you're using Rails 7 this will already be installed and ready for you to use.
Set up a Turbo Frame for each of your sections and have the src element point to the route you want and that controller will be responsible for populating the frame.
Related
In Rails why would I ever use partials? Explain it as if I'm 5 years old. I simply do not get why anyone would ever use them.
First thing, Please have a read here Official Rails guide for partials .
Now some benefits
It keeps your view clean and systematic, DRY Philosphy .
The most important where
partial comes into picture is when you want to reuse some of the
component amongst various view. Usually developer create a kind of
shared/common folder where partial sits and are used amongst
various view.
It’s also easy to conditionally load partials using Rails’ “if” or “unless” statements
It is beneficial where a template needs to iterate over a collection and render a sub template for each of the elements.
Your different partials can also have different layouts.
The Partial API here list all the various methods which will make you understand it's benefit.
Separating your view into partials can also help in in proper fragment caching (Fragment Caching) of some portion of you webpage. Better management.
If you are into Metaprogramming then you can add that flavor in your partials too, by creating dynamic helpers. As Stackoverflow answer here
They are a handy way to avoid repeating yourself.
For example, you may have several pages that display a menu. Instead of repeating the markup for the menu in every view, you just throw it in a partial and render on every page.
There are other cases where complex views are made more manageable by breaking them into several partials.
You normally use partials to reuse code: let's say you have a list of posts and each post has a small preview with image, title and excerpt. In your blog homepage you have a list of posts, when you group posts by year, you show a list of posts, when you search for a term you have to display a list of posts.
Instead of repeating the logic to display a post preview, you can move that logic to a partial and keep referring to that whenever you need it. You can keep your code DRY and write less code. Moreover, if you realize you want to add something new, you can just change the partial instead of going and hunting for the templates which display the post previews all over your application.
Well, for the exact same reason that you want to use methods, which is reusing code. Say you have a status area in your application, that you want to show in different places. You can just put the view code for that status area in a partial and then use that partial on the corresponding pages.
Since partials can also take parameters, they make it very easy to reuse view code. Also, you can make partials dedicated for certain models of your application. This way, you can just call render #model and the correct partial is picked by naming conventions.
A partial allows you to separate layout code out into a file which will be reused throughout the layout and/or multiple other layouts.
For example, you might have a login form that you want to display on 10 different pages on your site. Rather than writing the form code 10 times, you can write it once in a partial, and in each of the 10 pages, simply include that partial at the appropriate place in the layout. If necessary, you can pass local instance variables to the partial to make them available to it.
That way, if you need to change the form, you only need to change the code in the partial, one time, rather than changing it 10 times across all of your layouts.
Here is the guide on partials: http://guides.rubyonrails.org/layouts_and_rendering.html#using-partials
And more discussion on getting data/variables into partials: Pass a variable into a partial, rails 3?
I'm rewriting an app to ZF2 and I got stuck on problem of aggregating views from many modules on one page. What I want to achieve is to separate functionalities into modules, but still be able to display their views/actions (not sure how to name it) on one page. Let's say I'd layout a page with 4 containers and each of them would display some view from 4 different modules. Is it possible, if yes then how? Or maybe my though process is wrong here (I'm set on separating those functionalities though).
I've tried defining same or similar routes (eg. Module1: /boo/[:yah], Module2 /boo/[:whatever]). It didn't work because first module loaded was apparently served. And it looks like a mess too.
I've read a little about view helpers, but seemed to be aimed at a different purpose of providing common functionalities across many views. Whereas what I need if something like a layouting helper, view aggregation or something. I've worked with a home-made framework before that had this concept of site controllers, that would fire up different controllers actions. I can't find a way to emulate this in ZF2.
I'd appreciate any suggestions.
I've been applying forward plugin for this purpose as described in the blogpost suggested by Sam. It doesn't look elegant, but then I can't think of anything better myself.
I've just finished going through my first book learning RoR and wanted to practice some more extending the project, but I'm at a bit of a loss for how to structure the additions I want to make and would appreciate some guidance.
Right now the application is separated by pages that have a model controlling the logic and a controller routing that logic to the view, but none of the pages have any cross-over in features. I want to create a page that has pre-templated features with logic from other models, sort of like widgets in WordPress, or plugins in Magento. If I had a Page model and wanted to inject a Bestsellers list in the view, or I had a Blog model and wanted to inject a list of products with a tag calling out to a template with all the markup already, what is the proper way to do this?
Would these have to be modules? Would I just create another view template for Catalog that I would call into the Page index view?
Nevermind, I found the answer to what I was looking for here
I am a little ashamed for asking so many questions, but I really want to learn.
In Sipke's blog a webshop is created. There is one specific question that boggles my mind when trying to do something similar.
Let me spell out the basic requirements:
User registration form and login, etc. This one is covered by the blog and it works nice.
Creating product parts and so on. This one is covered and no problem there.
Ordering by filling in an order form and making the payment. See down
Having the order page maintainable by customer. See down.
Viewing your own orders and their status. See down
Maintaining customers and orders from backend system. This one is covered by the blog and I need to do some work there yet.
As for items regarding creating orders and viewing your orders. I have followed the approach for creating records and using standard MVC controllers. But then I encountered problems:
Menu for orders page. This I had to do manually after installing the module.
The order page itself. I had to create the view including title and so on. But I can imagine a customer wanting the order page on another menu and with a different title. And maybe add even some own content to the ordering page. This I couldn't achieve by using standard MVC approach. So maybe I am using the wrong approach here. So I was thinking about using contentparts for creating an order and displaying them and using the drivers and handlers for that. But before I go down that road and refactor everything I want to know if that is the right approach. A downside could be that once the module follows that route it can then not so easily be reused with customers that have other cms's capable of hosting an MVC3 module.
So when to use drivers, handlers and contentparts and when to use standard controllers and views.
You should use Drivers and Parts (with Handlers if needed) when you want to create functionality for content items. E.g. if you want to display a custom media with all products, you could create a Part (together with its Driver, etc.) to handle that. Read the docs on Parts.
If the functionality is not tied to content items the most possibly you want to use the standard MVC toolbox, it's fine. Look at the built-in modules how they do that. E.g. the Blog module uses controllers and views to show the admin UI, but has parts to enhance the functionality of for example the Blog content type.
To make things more complicated you can employ ad-hoc content items to build a page that you'd normally do with simple views, but that's an advanced topic :-).
I have a Rails 3.1 "blog" type app and my Post#index has become a sort of overview (or dashboard or sorts) into the whole system. The main content is pulled from the Post model but a sidebar contains info from an Event model, there are other snippets from a News model, etc…
Post#index is a busy action that has to populate many instance variable before /view/posts/index.html.haml gets a call to render and then the many layouts and partials go to work.
Being as some of these other areas are self-contained, so to speak, I'm wondering if there's a better "Rails way" to approach this? Perhaps I should be looking at encapsulating the Event sidebar (which is effectively Event#index) into some kind of entity that can be re-used perhaps in other views? And, if so, how?
What are the options?
You might checkout
http://cells.rubyforge.org/
I would look into widgetizing it. A framework that I looked into in the past was: http://apotomo.de/ This provides a nice clean way to widget"ize" as well as callback functionality (Ajax) for specific widgets.