Refactoring - Cleaning up a Controller

This topic is for the [Cleaning up a Controller] exercise in the [Refactoring] trail. Post any questions, corrections, or pointers you have to share with other Upcase subscribers.
[Cleaning up a Controller]: https://exercises.upcase.com/exercises/cleaning-up-a-controller
[Refactoring]: Refactoring Code | Code Refactoring Online Tutorial by thoughtbot

I can’t get bin/setup to work.
bundle install seems to work fine.

running rake gives me:
I get PG::ConnectionBad: could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket “/tmp/.s.PGSQL.5432”?
Using rails 4.1.1
Using ruby 2.2.2p95

Any ideas?

Hello @flocela, I’ve run into this myself a few times. It means that postgres is not running and needs to be restarted. If you’re using an OS X / homebrew install, the following might do the trick (run in your shell):

rm /usr/local/var/postgres/postmaster.pid && cd ~/Library/LaunchAgents && launchctl unload homebrew.mxcl.postgresql.plist && launchctl load -w homebrew.mxcl.postgresql.plist

If you’re on another OS or that doesn’t work, I’d suggest googling the error message and see what you can find on StackOverflow or similar.

thanks Chris,
Unfortunately that didn’t work. Have tried stackoveflow answers, but no luck. I’m not keen on figuring out what’s wrong with this one application, unless this means that new rails 4 applications using postgres won’t work.

Do you think I won’t be able to use postgres on any application? You don’t have to answer that, I mean that’s not a rails question.

Am off to other trails for now.

victory!
For anyone who has this problem.
I didn’t have postgres on my computer(mac).
So. . .
Downloaded postgres from: http://postgresapp.com/
Then I tried rake again and got same error. Then I tried psql -h local host and got same error.
Then I kept thinking I had to connect the database to a port. However, I didn’t have the password to do this. Then I tried to get the password by changing the pg_hba.conf, but in the end decided I didn’t know what I was doing there, so didn’t.

So finally, all I had to do was start the server.
pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start

-flo

1 Like

Are we supposed to be able to run rails server and have the views show up on local host?
When I run rails server I get
‘Usage:
rails new APP_PATH [options]’
so it doesn’t really think this is a rails app.
Okay so then I copy a config.ru file and run rails server. Then I get
‘Notice: server is listening on all interfaces (0.0.0.0). Consider using 127.0.0.1 (–binding option)’
Then the page shows
‘Missing secret_key_base for ‘development’ environment, set this value in config/secrets.yml’

I also tried it with the binding option.

I don’t know if this has anything to do with it, but when I call ./bin/setup, it looks like it works but gives this message at the end.
‘/Users/flo/.rvm/gems/ruby-2.2.1/gems/activesupport-4.1.1/lib/active_support/values/time_zone.rb:285: warning: circular argument reference - now
WARNING: db:test:prepare is deprecated. The Rails test helper now maintains your test schema automatically, see the release notes for details.’

I’m just going to start refactoring and only pay attention to the tests, not the views. Write me back if you know what I’m doing wrong. : )

I would have expected the tests in spec/controllers to be unit tests, but this controller test seems more like an integration test. What’s the best practice for testing controllers? Do people ever test controllers with unit tests?

Yep, I’m having the same issue!

After some digging around, it looks like this app was never designed to be run from the server.

Yep, as long as the tests run, you should be good to go.

I ended up using chained scopes with optional parameters, and as the solution is a bit different from anything I have seen (including the featured solution), I am really interested in hearing some views, what others think about this solution, and if there are any caveats I should know about.

Thanks!

~

Expense class featuring only the scopes (there is of course more in the actual solution)

Expense < ActiveRecord::Base
  default_scope { where(deleted: false) }

  scope :by_user, -> (user) { where(user: user) }

  scope :approved, -> (approved) do
     return unless approved
     where(approved: approved)
  end

  scope :min_amount, -> (min_amount) do
     return unless min_amount
     where('amount > ?', min_amount)
   end

   scope :max_amount, -> (max_amount) do
     return unless max_amount
     where('amount < ?', max_amount)
   end
end

The scopes can then be chained like so, in ExpenseController

   @expenses = Expense.by_user(@user)
                       .approved(params[:approved])
                       .min_amount(params[:min_amount])
                       .max_amount(params[:max_amount])
1 Like

I personally did not like how expenses are nested within users. So in my expenses_controller, I use current_user instead. But while I tried to setup login_as helper method within my feature test, after adding the steps needed (How To: Test with Capybara ¡ heartcombo/devise Wiki ¡ GitHub), I came across this error: Insecure world writable dir /usr in PATH, mode 040777 /Users/ericchen/Upcase/cleaning-up-a-controller/spec/spec_helper.rb:2:in '<top (required)>': uninitialized constant Warden (NameError). Any idea as to how to fix this? Or is there a better approach?

Thank you Flo!!! Was having the same postgres issues but this worked like a charm!

This is awesome but one small correction: in your :approved scope it should be return unless approved.nil?. Since approved is a boolean that can either be true or false, you don’t want the scope to return early when the approved is false

Installing the gems have been awful. The JSON gem v 1.8.1 wouldn’t work on any Ruby 2.1.x to 2.4.x because it’s outdated and activesupport gem relies on it and refuses to work with the newer ones. Installing newer versions of all gems breaks the code. I had to install Ruby 2.0.0 which is outdated and not recommended.

Please update the codes to work with newer or at least stable gems that are supported with stable versions of Ruby. I had to waste an hour for this.

1 Like

Yet again another trail that doesn’t allow me to run rake without having to fix errors. I feel so cheated having paid for this.

1 Like

After researching some ways automating starting a Postgres servers, I came across a feature of Homebrew that allows you to make use of macOS’s launchctl but with a simple Hombrew feature: brew services.

To setup use the sequence of commands:

  • brew tap homebrew/services - more on what this does by reading Homebrew :: brew tap and Homebrew :: services
  • brew services start postgresql and you should get a confirmation message Successfully started `postgresql` (label: homebrew.mxcl.postgresql)

At this point you can run the command to setup you database and tables: bin/setup.

For more info see this post from the Thoughtbot blog which I used: Starting and Stopping Background Services with Homebrew.

Hope this helps

Hello Upcase mentors,

Just wanted to note that are a few stumbling blocks for people who are trying to refactor this small Rails app. Most of them are related to the amount of depreciated code in the codebase. For example the renaming of “FactoryGirl” to “FactoryBot” and the reference to ActionDispatch::ParamsParser::DEFAULT_PARSERS in config/initializers/disable_xml_params.rb.

Would it be too much to ask Upcase to update the code in the trails? Among the people who have paid for access to material on this site, I am not the only one to have requested this.

Responding to this because I also was encountering the error below when doing bin/setup

An error occurred while installing json (1.8.1), and Bundler cannot continue.

Switch to Ruby v. 2.3.x using your favorite version manager and do gem install rails if you haven’t already. Inside the folder, run bundle update rspec-rails and you should be good.