I’m new to Rails. I’m using Service layer to keep my controllers thin. All my service layer files are located in app/services/domain, app/services/application, app/services/infrastructure. For example here is the my company service:
class CompanyService
def self.create(params)
company = Company.new(params)
rst = true
ActiveRecord::Base.transaction do
begin
company.save!
rescue ActiveRecord::RecordInvalid
rst = false
rescue ActiveRecord::StatementInvalid
rst = nil
end
end
return company, rst
end
def self.update(params)
company = get_company(params[:id])
rst = true
ActiveRecord::Base.transaction do
begin
company.old_category_ids = company.category_ids
company.assign_attributes(params[:company])
decrease_category_ids = company.old_category_ids-company.category_ids
decrease_counters(decrease_category_ids)
increase_category_ids = company.category_ids-company.old_category_ids
increase_counters(increase_category_ids)
company.save!
rescue ActiveRecord::RecordInvalid
rst = false
rescue ActiveRecord::StatementInvalid
rst = nil
end
end
return company, rst
end # end update
And here is the company controller:
def create
@company, rst = CompanyService.create(params[:company])
if rst == true
redirect_to(admin_companies_url, notice: "Company was successfully created.")
elsif rst == false
render active_admin_template('new.html.erb')
else
redirect_to admin_companies_url, notice: "Something went wrong. Please try again."
end
end
def update
@company, rst = CompanyService.update(params)
if rst
redirect_to admin_company_url(company), notice: "Company was successfully updated."
elsif rst == false
render active_admin_template('edit.html.erb')
elsif rst == nil
redirect_to admin_companies_url, notice: "Something went wrong. Please try again."
end
end
def destroy
CompanyService.destroy(params[:id])
redirect_to admin_companies_url
end
So I have two questions:
- I know my controller code is not good. How to improve it?
- My services are not automatically loaded in production and development environment. Why?
Sorry for poor English. Thank you for every advice and help.
Is there a reason you dont want to use the models and abstracting model interactions through services?
to load your services automatically you should include services path in autoload config.autoload_paths inside your config/application.rb
You also have a double check on bad record (invlid record or invalid statement), your user experience is going to be the same regardless of why the record was not saved so there is no reason to have nested ifs. Your controller should just know if the action was successful or not