Help with the has_one model implementation

I keep getting the following error:
NoMethodError in Students#show
undefined method `student_accounts_path’ for

I am trying to implement a has_one model. I followed the rails guide
that used the :post has_many :comments example and tweaked it a bit.

my routes.rb file looks like this:
resources :students do
resource :account

My Students.controller, Account.controller files are attached.
Along with the /app/views/students/show.html.erb file

I have no idea what I’m doing wrong.
Can anyone please help me?


rake routes

  • and you will see, there really isn’t defined a student_acounts_path

resources :students do
resources :accounts

or alternatively in your show (if you want to add a show, edit or
update-action in your accounts_controller without an :id param)

form_for [@student, @student.build_account], :url =>

B. Pieck

Thanks for your tips Bente,

I ran rake routes, and this is what I got:
student_account POST /students/:student_id/account(.:format)

I thought my routes.rb file HAD to be like this:
resources :students do
resource :account

because my Student model only ‘has_one’ Account (not a has_many)

I changed my form_for to:
form_for ([@student, @student.build_account], :url =>

And I am no longer getting the ‘NoMethodError’ BUT the account
information is not being saved to the accounts table.

What key concept am I not understanding?

Hi Ayesha,

it might be a typo in your routes:

resource :accounts insted of resourceS :accounts

Also please if you want to connect these tables you need a couple of
things, not only nested routes.
You also need:

  • has_many relationship in student.rb
  • belongs_to relationship in account.rb
  • you need to add 1-1 table column to both tables which refers to each
    others. Best way to do it with migrations like “rails generate
    migration AddStudentIdForAccounts” and AddAccountIdForStudents. Follow
    Fill these, then run “rake db:migrate”
    Finally you need the proper nested routes you mentioned above, also
    controllers and views in place with well-named methods.

So in short way:
2 tables refers to each other (with 2 migrations),
2 model files refers to each other,


PS. Highly recommend you this tutorial instead of Guides first:
this helped me a lot in understanding full MVC in action!

I think I figured it out.
It was to do with my @student.build_account in the students#show method.
(And as per my original post, I think I had that in my form_for tag).

Because I’m returning to the same page, the foreign key was continually
being ‘built’.

My students controller looks likes this:
def show
@student = Student.find(params[:id])
@account = @student.account
if @account.nil?
@account = @student.build_account

respond_to do |format|
  format.html # show.html.erb
  format.json { render json: @student }


And my accounts controller looks like this:
def create
@student = Student.find(params[:student_id])
@account = @student.create_account(params[:account])
redirect_to student_path(@student)

And my app/views/students/show.html.erb is attached.

Hi YogiZoli,

Thanks for your post.

I think you meant has_one instead of ‘has_many’ (in your first bullet
point for student.rb).
I tried what you suggested, and my routes.rb file has
resource :accounts

I also went back to my original “form_for” text as per my attachment and
I no longer see that NoMethodError (YAY!) that I first posted up.

I figured out why (at least i think i did) my ‘insert into accounts’
would delete when I rendered the show.html.erb file after creating an
account… I had the text “:dependent => :destroy” in the model.rb file

I’ve updated my models to have that 1-1 relationship.
While I was testing it out, I noticed the following in my server logs…

Started POST “/students/4/accounts” for at 2012-04-01 21:16:19
Processing by AccountsController#create as HTML
Parameters: {“utf8”=>“✓”,
“account”=>{“name”=>“acname1”, “number”=>“1111”}, “commit”=>“Create
Account”, “student_id”=>“4”}
Student Load (0.4ms) SELECT students.* FROM students WHERE = 4 LIMIT 1
(0.4ms) BEGIN
SQL (0.5ms) INSERT INTO accounts (created_at, name, number,
student_id, updated_at) VALUES (‘2012-04-01 11:16:20’, ‘acname1’,
‘1111’, 4, ‘2012-04-01 11:16:20’)
(0.7ms) COMMIT
Account Load (0.3ms) SELECT accounts.* FROM accounts WHERE
accounts.student_id = 4 LIMIT 1
(0.1ms) BEGIN
(0.1ms) COMMIT
Redirected to http://localhost:3000/students/4
Completed 302 Found in 11ms (ActiveRecord: 2.4ms)

Started GET “/students/4” for at 2012-04-01 21:16:20 +1000
Processing by StudentsController#show as HTML
Parameters: {“id”=>“4”}
Student Load (0.3ms) SELECT students.* FROM students WHERE = 4 LIMIT 1
Account Load (0.4ms) SELECT accounts.* FROM accounts WHERE
accounts.student_id = 4 LIMIT 1
(0.1ms) BEGIN
(0.3ms) UPDATE accounts SET student_id = NULL, updated_at =
‘2012-04-01 11:16:20’ WHERE = 4
(28.6ms) COMMIT
Rendered students/show.html.erb within layouts/application (36.4ms)
Completed 200 OK in 46ms (Views: 14.5ms | ActiveRecord: 29.8ms)

After entering the account details I make it redirect to the
app/views/student/show.html.erb view because I basically want to just
update the “show” page. BUT I can see that the student_id is being
updated to NULL - why is that?