I have a controller that I feel has too many instance variables.
The controller is pulling data from various places and it feels really sloppy. I have watched some Sandi Metz talks, read books, and other research, and I want to have good practice but I just don't know what to do here.
This method is pulling all the data and sending it to my view and I am able to get it to work, I just know this isn't a good way to go about it and I am hoping someone can point me to some code samples, documentation, videos, or help me understand how to implement a better style.
I have searched on SO and Google but I mostly find people saying to send a hash or JSON to the view, and I want to know if that is ideal before I start on that.
The Client, Project, Person, Role controllers and models have really similar code and I am working on refactoring it to be more DRY.
For example the Client, Project, Person, and Role financial controllers have almost the exact same controller index code as this. :(
I would be happy to add more code if that would help!
This is the project_financials_controller#index
It's pretty much taking in the data from the view and pulling a bunch of data from the database and sending it to a view. I'm currently using only the index method because it was only supposed to be a 'view' but now we can add filters such as time, different clients, etc so I think I need to break it out somehow.
I do have a financial_reports_nav model that this is calling that I could maybe use more, Or even make a financial_reports_controller that pulls the data from the appropriate model and I wont even need the 4 different controllers...
I am totally open to any input/criticism!
def index
# CPPR = Client, Project, Person, Role
@financial_type = 'project'
@financial_params = params
# This pulls the timeframe from the view and figures out the dates requested. (eg. "Last Week")
@timeframe = Financial.time_frame(@financial_params[:timeframe], current_company.timezone, params[:start_date], params[:end_date])
# This grabs all the data required to recall this financial report view at a later time
@financial_nav = FinancialReportNav.set_financial_type(@current_user.id,@financial_type, @start_date, @end_date)
# Grab all active and inactive people for client
@people = Person.active.all
@deleted_people = Person.inactive.all
# This sends over all the info needed to generate the financial reports
@project_financial_populate = Financial.new(@financial_params, @financial_type).populate_project_financials(current_company.default_hourly_cost, current_company.billing_rate, @timeframe[:start_date],@timeframe[:end_date])
# This just pulls all the data from the database that the @project_financial_populate just populated (Can't we just use that??)
@financial_rows = ProjectFinancial.all.map { |p| [ p.project_id, p.billable_hours, p.revenue,p.real_rate, p.hourly_expense, p.labor_expense_total, p.salary_expense, p.gross_profit, p.profit_margin, p.missing_hourly_expense, p.missing_billable_rate ] }
# Using the same view for CPPR's
# Clients has an items count, so we just stuff everything into the first array slot
@items = [1]
# If these are not null then they show an option to change the financial filter type.
@filter_by_client = Client.find_by('id = ?', @financial_params[:filter_by_client])
@filter_by_project = Project.find_by('id = ?', @financial_params[:filter_by_project])
@filter_by_person = Person.find_by('id = ?', @financial_params[:filter_by_person])
@filter_by_role = PersonRole.find_by('id = ?', @financial_params[:filter_by_role])
# This pulls a list of CPPR's that have tracked time in the requested timeframe
@project_list = Financial.project_list(@timeframe[:start_date], @timeframe[:end_date])
@client_list = Financial.client_list(@timeframe[:start_date], @timeframe[:end_date])
@people_list = Financial.people_list(@timeframe[:start_date], @timeframe[:end_date])
end