0

this is my first question here and I am currently trying to build my first Ruby on Rails app so this question might be kind of basic.

The Problem:

I want a form on the root site which consists of only two fields, email and password for a user model. Depending on whether the email address that was typed in already exists or not, the form should forward the request to the 'users#create' (i.e. create a new user) or the 'sessions#create' (i.e. Sign the user in ... if the password is correct)

What I tried:

To solve this I created a new action in the pages controller called 'decide' and pointed the form to that page.

It basically looks like this:

def decide
  if User.find_by_email(params[:email])
    # Copied in all of the code from sessions#create
    # with a redirect at the end so a /decide page doesn't get rendered
  else
    # Copied in all of the code from users#create
    # with a redirect at the end so a /decide page doesn't get rendered
  end
end

--

Now this works and I'm pretty proud of myself that I figured it out as a complete beginner, but I can hear experienced programmers crying out in agony at this code. I'm pretty sure this is not the "Rails Way".

I repeat a large amount of code and I feel like I'm putting something in a controller that wasn't made for that purpose.

Another problem is that I can't get my rspec integration test to work, which basically goes to the root_path, fills in the form with a new user, hits the button and expects a success flash... but the test gets returned an empty html document on pressing the button. Although it works perfectly fine when I do the same thing in a browser.

So I figured:

Couldn't you somehow put the above if statement in the routes.rb file and redirect the request to the respective controller and action?

If so how?

Or does anyone have a different idea how to accomplish this?

Thank you,

-Konstantin

KonstantinK
  • 757
  • 1
  • 8
  • 23
  • As far as your RSpec problem goes, it may be worth asking another question with some more detail, ie: your specs, more code, etc. – dnch Jun 09 '11 at 07:56

2 Answers2

1

Actually, that's a fairly solid way of handling the problem.

Routes in Rails are only supposed to be a simple way of mapping URLs to code. Logic like that belongs exactly where you've placed it: in the controller.

dnch
  • 9,565
  • 2
  • 38
  • 41
  • +1 @KonstantinK As an aside, there's no need to write your own aurhentication stuff unless you need something specific, check out https://github.com/plataformatec/devise – Ant Jun 09 '11 at 08:14
  • Well, thanks for the answer. So the pages controller really is the right place... But isnt there a way to not need to paste in the other create codes? I tried forwarding via redirect_to params.merge! :controller => :sessions, :action => :create but the problem is that since passwords get filtered they don't get passed along as params. I guess I would need to forward the entire request and not redirect it – KonstantinK Jun 09 '11 at 11:29
1

Answering my own question:

Turns out the spec problem was simply due to webrat not following redirects in rails 3. It's actually a common problem that is solved ->here for example.

So at least that problem is out of the way.

Community
  • 1
  • 1
KonstantinK
  • 757
  • 1
  • 8
  • 23