views:

1016

answers:

3

So I'm building a rails app for high school students and I've hit a problem when it comes to creating users.

I want the students to only be able to create accounts if they select their school and type in their school's password correctly.

What is the correct / easiest way of doing this? Should I create a gatekeeper to the user#new action that they have to pass first or if their a way that on the same page a student can submit to forms. One would be the regular username, email, password using:

form_for @user do
  ...
end

But then creating another form for the high-school / high-school password selection.

Ideally the controller would be able to get the params of the high-school form, validate those, then go on to create the user from the user params.

Is this possible using rails?

My setup: Rails 3 and Ruby 1.9.2dev

Thank you!

A: 

I'm not familiar with Rails 3, but this'll certainly work with Rails 2. Some adaptation might be necessary.

Providing your User model would help, but I'll assume that it's something like: a User belongs_to :school, and a School has a field named password. In your User model you can have something like:

validates_associated :school
attr_accessible :school_password

def validate_on_create
  unless self.school_password == school.password
    errors.add :school_password, "incorrect password, please try again"
  end
end

Then you can have a select box in the form, like

form_for @user do |user|
  user.select :school...
  user.password_field :school_password
end
Colin Curtin
+2  A: 

You can do this with fields_for (http://apidock.com/rails/ActionView/Helpers/FormHelper/fields_for)

Your view will look something like

form_for @user do |f|
  fields_for @school do |school|
    school.text_field     :name
    school.password_field :password
  end

  f.text_field     :username
  f.text_field     :email
  f.password_field :password
  f.submit "Submit"
end

Then in your controller, params[:user] will represent the user data, and params[:school] will represent the school name/password.

You can then validate the correct school password before creating the user.

jrallison
I'm getting a "undefined method `model_name' for NilClass:Class" error with this implementation. Any ideas?
Eric Koslow
Did you instantiate a @school object? If you don't want to instantiate a school object, you can change the fields_for line to: "fields_for :school do |school|".
jrallison
Got it! Thank you!
Eric Koslow
A: 

jrallison is right about fields_for, but I would suggest considering whether it's strictly necessary to do both on the same form.

What you're describing with the school name and password sounds a lot like user authentication. It might not be a "user" in the sense of a single person, but in this case the "user" is the school. Maybe you should treat it that way: have a separate login form, create a session if they succeed (so that they won't have to type their school's password over and over again later on), and do the standard flash messages and such if they fail.

At that point, the form you need is simple and single-model. And if other features become necessary later on that also need the school password, you're already a step ahead.

SFEley