All threads / Rails 5.2 ActiveSupport CurrentAttributes & Basecamp 3 Account ID URL Scheme Discussion

Ask A Question

Notifications

You’re not receiving notifications from this thread.

Rails 5.2 ActiveSupport CurrentAttributes & Basecamp 3 Account ID URL Scheme Discussion

Reply

How do you end up testing this with Minitest?
All controllers actions fail because env["REQUEST_PATH"] is nil

NoMethodError: undefined method split' for nil:NilClass
lib/account_middleware.rb:8:in
call'

Yeah, I'm wondering about this too.

Obviously there's a follow up episode which explains how to incorporate the middleware into System Tests, but there's presumably also a way have Integration Tests while using the account middleware.

Any idea how to handle that?
I have the same issue with RSpec :(

Reply
Hi Chris,

This is great, but just wondering how I might be able to use an account_name rather than the account_id?

So would like the URL to look like: sample.com/coolaccount/posts/1
So I managed to get it mostly working using:

class AccountMiddleware
    def initialize(app)
        @app = app
    end

    def call(env)
        _, username, request_path = env["REQUEST_PATH"].split('/', 3)

        if username
            Current.user = User.where(username: username)

            env["SCRIPT_NAME"]  = "/#{username}"
            env["PATH_INFO"]    = "/#{request_path}"
            env["REQUEST_PATH"] = "/#{request_path}"
            env["REQUEST_URI"]  = "/#{request_path}"
        end

        status, headers, body = @app.call(env)
        [status, headers, body]
    end
end
The problem here, of course, is that I have a problem with URLs such as 'users/sign_up/' where Rails thinks username is 'sign_up'


You will need to whitelist some routes (sign_up...) based on 
env["REQUEST_PATH"]
with a regular expression and skip middleware for those paths. (similar to what Chris did with ensuring account_id is a number)

Reply
What's the difference with this approach using middleware, and simply taking accounts out of the path in routes?

resources :accounts, path: '', except: [:index] do
  resources: projects
end

(newbie question)
Reply

So how would you set the account_id in the URL when a user logs in? surely its not as simple as just setting Current.account = user.account_id ?

You could do that initially. Although if you want to prevent users from hijacking the URL, you'll also need to protect your controllers by ensuring that the URL account_id always matches the current_user account ID. For example:

redirect_to root_path(script_name: "") unless current_user.account == Current.account
Reply
Join the discussion

Want to stay up-to-date with Ruby on Rails?

Join 37,629+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.

    logo Created with Sketch.

    Ruby on Rails tutorials, guides, and screencasts for web developers learning Ruby, Rails, Javascript, Turbolinks, Stimulus.js, Vue.js, and more. Icons by Icons8

    © 2020 GoRails, LLC. All rights reserved.