Carpela
Carpela

Reputation: 2195

has_one relationship without nested_form

I'm trying to implement a has_one relationship through a basic form and am getting completely stuck.

I seem to have tried huge numbers of combinations of things in controllers and forms but don't seem to be getting anywhere.

I have a phone number for which I use an external service populated by an api.

Eventually I would like to have all the phone numbers of this type set up for this, but right now I'd be happy with getting just one working.

parent.rb

has_one :clever_phone

And a phone model

clever_phone.rb

attr_accessible :number, :parent_id, :prefix, :country_iso
belongs_to :parent

Controller

clever_phones_controller

def new
@parent = Parent.find(params[:parent_id])
@clever_phone = @parent.build_clever_phone


def create

@parent = Parent.find(params[:parent_id]
@clever_phone = Parent.create_clever_phone(params[:clever_phone])

View I really don't want to do a nested form from the parent here as I have some complicated code which generates information used in the creation through an api that sits, correctly I think, in the clever_phones_controller

@simple_form_for @clever_phone do |f|

= f.input :country_iso, as: :country, :iso_codes => true, priority: ["gb"]
= f.input :prefix

= f.submit

Routes

 resources :parent do
   resource :clever_phone
 end

My issue is that the params for @parent don't seem to be being passed to the create method in the controller and thus I get a 'Can't find parent without ID' error

If I try it as a nested form I get NoMethodError undefined method 'parent_clever_phones_path' When in fact I've not used that, only parent_clever_phone_path (note the absence of plural).

I'm sure this should be really simple but I've stared at it for hours now and am at the end of my tether...

Any ideas?

Upvotes: 2

Views: 174

Answers (2)

Carpela
Carpela

Reputation: 2195

Right: Worth putting in the solution that finally worked. Thanks to Rich Peck for getting me halfway there... model

parent.rb
  has_one :clever_phone

clever_phone.rb
  belongs_to :parent  

view

simple_form_for @clever_phone, url: parent_clever_phone_path(@parent) do |f|

-----
f.input :parent_id, :value: @parent.id
-----

routes

 resources :parent do
   resource :clever_phone

controller

def new 
....
@parent = Parent.find(params[:parent_id])
@clever_phone = @parent.build_clever_phone

def create
@parent = Parent.find(params[:parent_id]
@clever_phone = CleverPhone.new(params[:clever_phone]

Unless you do build_clever_phone the parent_id won't populate. I couldn't get @parent.create_clever_phone to work, but this seemed to do the trick...

Hope that saves somebody a days work...

Upvotes: 1

Richard Peck
Richard Peck

Reputation: 76774

Okay, there are several issues which you need to contend:

--

Variable

The reason why @parent params are not being passed is because you've not included them in your form. This is where nesting your forms would come in very handy - passing your parent params, and your clever_phone params in a single call

Since you don't want to do this, I would recommend at least populating a hidden field with the parent_id that the clever_phone is associated with:

#app/views/clever_phones/new.html.erb
= simple_form_for @clever_phone do |f|

= f.input :parent_id, as: :hidden, value: params[:parent_id]
= f.input :country_iso, as: :country, :iso_codes => true, priority: ["gb"]
= f.input :prefix
= f.submit

--

Route

Alternatively, you have to make sure you're able to create the correct route for your form (as I think the @parent = Parent.find params[:parent_id] is not being called on your create method:

#app/views/clever_phones/new.html.erb
= simple_form_for [@parent, @clever_phone] do |f|

This will give you the ability to point your create action to the nested version of your route; hence providing the parent_id param for you

--

Having written, this I don't think it will address the core of your issue. If you need more information, please write a comment & I'll happily work to create a more appropriate answer!

Upvotes: 1

Related Questions