Reputation: 1997
My web app, up until this point, has been fairly straight forward. I have Users, Contacts, Appointments and a few other things to manage. All of these are easy - it's just one model per section so I just did a scaffold for each, then modified the scaffolded code to fit my need. Pretty easy...
Unfortunately I am having a problem on this next section because I want the 'Financials' section of my app to be more in depth than the other sections which I simply scaffolded. For example, when the user clicks the 'Contacts' link on the navigation bar, it just shows a list of contacts, pretty straight forward and is in line with the scaffold. However, when the user clicks the 'Financials' link on the navigation bar, I want to show the bank accounts on the left of the page and a few of the transactions on the right.
So the financials tab will basically work with data from two models: transactions and bank_accounts. I think I should make the models (transactions & bank_accounts) and then make a controller called Financials, then I can query the models from the Financials controller and display the pages in app/views/financials/
Am I correct in this app layout? I have never worked with more than the basics of scaffolding so I want to ensure I get this right!
Thank you!
Upvotes: 5
Views: 8046
Reputation: 4799
It sounds to me as if you want two views:
However, when the user clicks the 'Financials' link on the navigation bar, I want to show the bank accounts on the left of the page and a few of the transactions on the right.the transactions on the right.
Keep in mind that one screen doesn't always mean one view in MVC. Conceptually, a view simply renders model data so the user can do something meaningful with it through controller actions. Rails muddies this up a bit by having you create a file in a views/ directory for each screen, so it's easy to think that one screen means one view. However, you can also call layouts within views in Rails, and these layouts are themselves views.
Putting transactions and accounts in separate views means each would have a controller to handle the user's interaction with each segment of data. The account controller, for example, would handle the event where the user selects an account to view additional information about an account. This would result in fetching transactions to show the user. The user could then interact with a transaction in an attempt to reconcile, void, or contest it. This would invoke logic in the transaction controller.
While this does a good job of removing the coupling from your controllers, this may seem like it couples the two views. However, the coupling is one-way: the account list includes logic specific to the transaction view (i.e. updating it when you select an account). The transaction view remains reusable in other areas of the application. For the most part, the account listing remains reusable as well, especially if you isolate it into a separate layout. The only difference you'd need for this specific screen is the handling of when a user clicks on an account.
If you merge everything into a financials view, it's still possible to keep things loosely-coupled, but it becomes more difficult to do so. The additional layer takes extra effort and may subconsciously guide you to merge everything up together.
Of course, either way works, and you could easily argue that the final design is an exercise that is best left to the developer's preference. I simply offer my interpretation of how one would most-accurately stick to the patters Rails attempts to guide developers to using.
Upvotes: 1
Reputation: 10498
If you are comfortable with scaffolding then i would suggest that you generate a scaffold for both
transactions: script/generate scaffold transaction financial_id:integer ...
bank_accounts: script/generate scaffold bank_account financial_id:integer ...
and financials script/generate scaffold financials ...
In your transactions model, add this:
class Transaction < ActiveRecord::Base
belongs_to :financial
end
In your bank_account model, add this:
class Bank_account < ActiveRecord::Base
belongs_to :financial
end
In your financial model, add this:
class Financial < ActiveRecord::Base
has_many :transactions
has_many :bank_accounts
end
Now from your financials controller you can use something like this:
def index
@financial = Financial.find(params[:id])
#This fetches all bank_accounts related to financial
@bank_accounts = @financial.bank_accounts
#This fetches all transactions related to financial
@transactions = @financial.transactions
end
In your views you can view all the bank accounts belonging to a particular financial by just doing this:
<% @bank_accounts.each do |bank_account| -%>
<%=h bank_account.something_here %> <!-- something_here is the column name corresponding to your bank_account table. -->
<%=h bank_account.something_here %> <!-- something_here is the column name corresponding to your bank_account table. -->
<%=h bank_account.something_here %> <!-- something_here is the column name corresponding to your bank_account table. -->
.
.
.
<% end -%>
In your views you can view all the transactions belonging to a particular financial by adding something similar:
<% @transactions.each do |transaction| -%>
<%=h transaction.something_here %> <!-- something_here is the column name corresponding to your bank_account table. -->
<%=h transaction.something_here %> <!-- something_here is the column name corresponding to your bank_account table. -->
<%=h transaction.something_here %> <!-- something_here is the column name corresponding to your bank_account table. -->
.
.
.
<% end -%>
Remember, while creating a new transaction/bankaccount use the id belonging to the particular financial. Hope this helps. Cheers! :)
Upvotes: 4
Reputation: 46193
I don't have a huge amount of experience with Ruby on Rails, or MVC work in general, but I think you're going about it the right way. You generally want a model object (and by extension, database table) for data-oriented resources... That is, your models should correspond to your "nouns". Your controller's actions are your "verbs", and to me it makes perfect sense to categorize them how you like.
In this case, I would say that putting a bunch of "verbs" under financials
, which interact with two model object types as needed, makes sense IF AND ONLY IF it makes sense to you for you to organize it like this. (Bear in mind that you can also evaluate how well organized and intuitive the corresponding URLs feel to you, though I'm sure most MVC purists would add that you should never just rely on examining the URLs!)
So in summary, I think you're doing everything right here, as long as it makes sense to you. Yes, you'll have to write your views and controller actions yourself, though you can start using ruby script/generate controller financials action1 action2 [...]
; that at least gives you skeletons of the view files and empty controller actions.
Upvotes: 0