user2784630
user2784630

Reputation: 806

Parent variables dissappear after child errors on create?

I have the following models User, Dad, Mom and Kid.

class Dad
 has_many :kids
end

class Mom
 has_many :kids
end

class User
 has_many :kids
end

class Kid
 belongs_to :mom
 belongs_to :dad
 belongs_to :user
end

I want to create a new Kid inside of the Dad and Mom.

resources :dads
 resources :moms
   resources :kids
 end
end

dads/1/moms/1/kids/new

# KidsController
def new
  @dad = Dad.find(params[:dad_id])
  @mom = Mom.find(params[:mom_id])
  @kid = Kid.new
end

def create
  @kid = current_user.kids.build(kid_params)

  respond_to do |format|
    if @kid.save
     format.html { redirect_to @kid, notice: 'Kid was successfully created.' }
     format.json { render action: 'show', status: :created, location: @kid }
    else
     format.html { render action: 'new' }
     format.json { render json: @kid.errors, status: :unprocessable_entity }
    end
  end
end

In my view I have the variables @dad.name and @mom.name but when an error happens when creating a kid, I get:

undefined method `name' for nil:NilClass

And I believe this to be because of me not having:

@dad = Dad.find(params[:dad_id])
@mom = Mom.find(params[:mom_id])

In the create action but that doesn't work either.

Couldn't find Dad without an ID

So how would I correct this?

EDIT

Here's my view.

Kids/new.html.erb

<% provide(:title, "Adding New Kid for #{@dad.name.titleize} and #{@mom.name.titleize}") %>
<% page_header "Adding New Kid for #{@dad.name.titleize} and #{@mom.name.titleize}" %>

<%= form_for @kid do |f| %>
  # kid fields
<% end %>

And how I get the provide and page_header.

ApplicationHelper

def full_title(page_title)
  base_title = "Kid Zone"
  if page_title.empty?
    base_title
  else
    "#{base_title} | #{page_title}"
  end
end

def page_header(page_title)
  content_for(:page_header) { page_title }
end

shared/page_header.html.erb

<div class="page-header">
  <h3><%= yield(:page_header) %></h3>
</div>

layouts/application.html.erb

<head>
   <title><%= full_title(yield(:title)) %></title>
</head>

Answer

Had to make my kid form be:

 <%= form_for [@dad, @mom, @kid] do |f| %>
      # kid fields
 <% end %>

and add to the create action just like my new action:

@dad = Dad.find(params[:dad_id])
@mom = Mom.find(params[:mom_id])

Upvotes: 2

Views: 73

Answers (2)

Babar
Babar

Reputation: 1202

Edited Answer

Since everything else is in order, and with the added information of your form, you need to create your form for nested resource like everything else in your app. so when it fails you will not lose information.

<%= form_for [@dad,@mom,@kid] do |f| %>
  # kid fields
<% end %>

and definitely you will find @dad and @mom in your create function as specified by Uri Aggasi

Upvotes: 2

Uri Agassi
Uri Agassi

Reputation: 37409

When you create @kid, you never say that @mom and @dad are his parents - they could be just a couple across the street. By the time @kid reaches create - @mom and @dad are gone (with their ids).

Therefore you need to assign @kid.mom and @kid.dad in the new action before rendering the view:

def new
  @dad = Dad.find(params[:dad_id])
  @mom = Mom.find(params[:mom_id])
  @kid = Kid.new
  @kid.mom = @mom
  @kid.dad = @dad
end

Upvotes: 1

Related Questions