Rails: aggregate multiple models into single view (think dashboard) - ruby-on-rails

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.

Related

What's the difference between controllers and actions in ruby on rails?

Can anybody tell me the difference between controllers and actions in ruby on rails?
I fetched this definition from the official rails guide:
A controller's purpose is to receive specific requests for the application. Routing decides
which controller receives which requests. Often, there is more than one route to each
controller, and different routes can be served by different actions. Each action's purpose is
to collect information to provide it to a view.
I am confused.
Please, make it as simple as possible since I am newbie!
Thanks!
Controllers are just Ruby Class files which have a series of instance methods inside
Basic Explanation
Rails controllers are basically files where actions (methods) are kept
Each time you access a Rails app, you're sending a request to the system. The various technologies inside Rails route that request to a certain action, where your code can use the passed data to perform some sort of action (hence the name). The actions are kept inside controllers to give the application structure
So if you access http://yourapp.com/users/new, it tells Rails to load the new method in the users controller. You can have as many actions in the controllers as you want, but you have to tell the Rails routes system they are there, otherwise they won't be accessible
Proper Explanation
Rails Controllers are just Ruby Classes, storing a series of actions
The "actions" (instance methods) work on passed data (params) to create objects that can either be passed to the model, or used inside other methods
Whenever you send a request to Rails (access a URL), it first uses the ActionDispatch middleware to send your request to the correct Class (controller) instance method (action), and then your code does something with that data
Your job as a dev is to connect the right controllers with the right models, presenting the right data the user at the right time
DISCLAIMER: I don't write code in Rails (never did). I write Sinatra modular applications and use the MVC model.
You first need to clarify the MVC model. The MVC is an approach to programming web applications (in RoR) or user interfaces in general. So MVC stands for Model-View-Controller. I will try to explain a bit, but in order to understand this, you need to practice and play with it.
The Model: If you remove the layers of abstraction, it's your database scheme. The way your application interconnects in order to retrieve information.
The View: The way these informations are retrieved elaborated and served. Essentially is what you, or the client, see in the browser.
The Controller: The controller is what interacts with the program to produce a requested view or to alter a model. You request a view when you access a chart with statistical information, and you alter the model when you input DATA on it. In Rails ecosystem, ActionController is a class with a set of predefined methods to help you perform easier and quicker standard Controller actions like update a form, etc.
So the Action Controller allows you to alter data to your models (the db), or request a route to view your data, etc.
Action is not separated from controllers, it's basically what controllers do :-). Everything else is static.
If you feel that these concepts are still hard to grasp, try building a very basic modular application in Sinatra, and you will have a ground level view of how things work.
Explanation by Analogy (simple explanation without getting too technical)
I work in a busy office. I bark out orders (i.e. 'requests') to my staff to get em to do stuff.
e.g.
Sometimes I want a document so I can read it.
“Ngozi, pass me the ABC.ASX EOFY results please?”
Yes sir!
Sometimes I ask my staff to edit an existing document:
“Sunita, can you edit that report on the state of the union address?”
“Sure!” is the response.
I organise my staff based on the type of work they do
But I have a little problem.....I have 10,000s of different types of documents. Sometimes I want to get: (I) sports results and other times I want: (ii) the evening news, while still at other times I want: (iii) a collection of Donald Trump's latest 4 am Tweets.
So I created a new system. I have a staff member directly responsible for each type of thing.
Ngozi handles ASX (Australian Stock Exchange) Financial Results. And when I want Ngozi to do something (i.e. perform some type of action) then I tell him what to do.
Sunita works mainly on politics. Sometimes I”ll ask her to something (e.g. write up a report – this is one type of 'action', or I'll ask her to bring me a certain document – another type of action - and she'll do it. I like to get Sunita to work on politics and Ngozi to work on financial results. It's best to keep their responsibilities separated.).
And Freddie works on anything pertaining to Queen.
Etc. etc.
The meaning of the analogy?
In this case, the controller would be the person – who's responsible for handling certain types of requests. And the “action” would be the particular specific thing that I want done:
e.g.
getting a document or
edit something or even
creating a new document.
Hope that clears things up.

Rails: Making widgets

I want to create a widget-like entity for my Rails app. For example, I'd like to be able to render a list of products marked as featured and have it work in any view file.
My first thought was to try to do this using a partial. Is this the best way? Will I be able to achieve my overall goal of having a widget I can inject anywhere? What's the best way to implement this?
Markup that is shared across many view files should be placed in a shared partial.
In this case, your partial will depend on having a collection of products available. You will need to query this collection in each controller action that corresponds to a page containing the widget. This sounds like a good way to do it to me.

Structuring a Rails CMS type application

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

How to use the same model with Rails for different controllers while staying RESTful

I need to have two separate pages on the site I'm planning to build that are very similar that I don't need to introduce new DB tables or models. I would also like to stay RESTful.
If I'm to use the same controller/model I will need to have new methods other than standard index, new, edit...etc which makes it non-restful or I will have to have a variable on page that identifies it and then inside each method I will render different view accordingly.
Another idea I got was to have separate controller and model but use the same DB tables and enforce the model to use the table although it doesn't match the convention.
I'm guessing there might be cleaner way to do this. Do you know any? if not which way do you suggest?
Thanks,
Tam
I'm not afraid of the restafarian police! Sometimes your controllers need more than the 7 actions (where's the get to confirm a delete, eh?), sometimes they will need less. That's just the way it is when you start to create real world software.
If the actions you're adding are not coherent with the actions that exist (for example off by just a little bit but still off in most actions), then we're talking about a new controller IMO - otherwise adding a few actions where you need to is ok in my book.

ASP.Net MVC View Structure

I just finished Scott Gu's Nerd Diner tutorial. I found it very helpful because it not only taught the basics of ASP.Net MVC, but also how to use with Repositories, Validation, Unit testing, Ajax, etc.. Very thourough, but still manageable.
However, I am curious about his site structure:
Specifically, he used this view strucuture for every object:
/ModelObject/Edit/
/ModelObject/Create/
Then extracted the common elements between the two views and put them into a partial.
I understand the logic, but it seems like it would lead to "view explosion" if you have even a moderate number of tables in your database.
Scott's really good, so I am assuming his structure is right. But I would like to know why.
Thanks!
[Edit for clarification]
I realize that many times it is necessary for there to be multiple actions (and views) to handle differences in creates and edits. It is the case of the very simple edit and create, where the only difference between the two actions is in one case the model has an ID and needs to be updated, and in the other case the model does not, so it needs to be inserted.
In this case, is the violation of the "Dumb View" rule by using the same view to handle both cases going to cause major problems?
The view structure is based on the controllers, not the model directly. In the Mvc methodology, you should have a view for each action (each public method, essentially) in a controller. The controller actions don't have to match up directly to each table in database but there is likely some sort of direct relationship between the number of tables in the database and the number of controllers and views. Controllers are higher level
It is standard to have CRUD type actions on the controller, when they are applicable:
Index: list the items
Details: view a specific item
Edit: edit an item
Create: new item
Delete: delete an item
Each of these actions will require a view (and sometimes more than one).
So, yes, you can collect a large number of views if it is a large application. The way to minimize the code is:
Extract shared functionality to partial views, as to keep the action views as small and simple as possible
Keep the views and controllers simple so that they are easy to maintain
Use AJAX to implement more functionality in one view
It's important to point out that any large application is going to have lots of forms. Whether it's Mvc or Web Forms, if there is a lot of data to work with, there are going to be a lot of forms necessary to do it.
It is true that this can indeed lend itself to a lot of views. However, I've found that in my real life applications, I'll have a number of tables that I don't have a 1:1 correlation to CRUD operations. While I certainly have data that goes into those tables, I've found that most times a view presents data from at least two if not three or more tables. Just like every other application, you've got to know what you're after so that you can plan things out. Any large size application is going to require quite a bit of planning up front (which would include analyzing the number of views/controllers for MVC).
It's only the small apps that you can sling together based on you hunches and past experience.
if you have a background as asp.net webforms developer, your answer is natural.
There are several questions, it depends on the point of view. At first, with asp.net-mvc we do not have fully-equiped server controls making many things for us, without a real awareness what they do. Now you have to type more code and have eyes like a surgeon on html.This way I can find a reasonable question for "view explosion"
Other projects follow more or less that structure, see the project by Rob Conery:
Mvc Storefront
PS: "Skinny controllers, Fat Model and… Dumb view"
[Update response to clarification]
Mhh.. I think there's no violation of "dumb view". The important thing is that the all the views has nothing to do with the code in the business logic layer or in your model. You can a have a button "Save", it is the controller has to know which action must be executed, insert or update.
On more reflection, this is what I am thinking:
Combining the edit/create views would be easy on simple models because
- Same properties displayed
- Same validations
BUT doing this would force you to either
- handle both the update and insert in the same action
- use a control statement in the view to determine which view action is used to update
Both options seem ugly and unnecessary when it is so easy to use separate actions and separate views with common code extracted into a partial.

Resources