Reputation: 358
I have seen the other links to this similar question but none of them seem to work in my case.
My update action is creating new records in mysql database
My app consists of 3 models
FashionModel
ModelProfile
and Measurement
They are defined as follows:
class FashionModel < ActiveRecord::Base
has_secure_password
has_one :model_profile
has_one :measurement
accepts_nested_attributes_for :model_profile
accepts_nested_attributes_for :measurement
end
class ModelProfile < ActiveRecord::Base
belongs_to :fashion_model
end
class Measurement < ActiveRecord::Base
belongs_to :fashion_model
end
The fashion_model_controller.rb
is as follows:
class FashionModelsController < ApplicationController
def new
@fashion_model = FashionModel.new
end
def create
@fashion_model = FashionModel.new(fashion_models_sign_up_params)
if @fashion_model.save
flash[:success] = "Welcome to Meriad"
session[:fashion_model_id] = @fashion_model.id
redirect_to edit_fashion_model_path(@fashion_model)
else
render 'new'
end
end
def edit
@fashion_model = FashionModel.find(params[:id])
@fashion_model.build_model_profile
@fashion_model.build_measurement
end
def update
@fashion_model = FashionModel.find(params[:id])
if @fashion_model.update(fashion_models_edit_params)
flash[:success] = "Saved!"
redirect_to fashion_model_path(@fashion_model)
else
render 'edit'
end
end
def show
@fashion_model = FashionModel.find(params[:id])
end
end
The fashion_model_edit_params
are
def fashion_models_edit_params
params.require(:fashion_model).permit(:first_name,
:last_name,
:email,
:password,
model_profile_attributes: [:id,
:location,
:bio, :gender,
:phone_number,
:rate,
:profile_image,
:birthdate],
measurement_attributes: [:id,
:feet,
:inches,
:bust,
:waist,
:hips,
:dress,
:shoes,
:hair,
:eyes])
end
I want something on these lines:
The fashion model signs up to the app through new.html.erb
(which is stored in the fashion_models
table)
The index.html.erb
contains a list of all fashion_models
with an option to edit information (update their profile)
The edit.html.erb
contains fields from the model_profiles
table as well as the measurements
table, both of which have the foreign keys to the fashion_models
table.
My fashion_models/new.html.erb
template is pretty straightforward containing first_name
, last_name
, email
, password
.
My fashion_models/edit.html.erb
template is something like:
<%= form_for @fashion_model do |f| %>
# fashion_model fields here
<%= f.fields_for :model_profile do |t| %>
# model_profile fields here
<% end %>
<%= f.fields_for :measurement do |t| %>
# measurement fields here
<% end %>
<% end %>
Now, whenever I edit a fashion_model/:id
, the model_profile
and measurement
create a new record in the database rather than updating the existing record. Also, when I am on the Edit Profile
page, none of the fields pre populate with the existing data. I have to manually enter all the data again.
First, I thought it was because of the build
methods, but when I remove them, the fields_for
do not display.
Appreciate any help!
Upvotes: 1
Views: 3865
Reputation: 358
So I finally figured out a way to do this. Hope it helps someone.
My problem was that I had 2 fields_for
inside one form_for
and I needed to update 2 models with to these forms.
I tired using callbacks like after_action :create_model_profile
and after_action :create_measurement
. And in both of these methods I tried to save fashion_model_id
as the :id
of the newly created fashion_model
.
But since callbacks are considered as code smells, I wanted a better solution.
Instead of creating a form_for @fashion_models
, I wrote a helper method as follows
# app/helpers/form_helper.rb
module FormHelper
def setup_fashion_model(fashion_model)
fashion_model.model_profile ||= ModelProfile.new
fashion_model.measurement ||= Measurement.new
fashion_model
end
end
and in my form_for
I used something like
form_for(setup_fashion_model(@fashion_model)) do |f|
...
end
This created a new instance of ModelProfile
and Measurement
if it did not persist in the database.
It then of course solved the problem of pre populating the fields which contained data.
This was it. Simple solution, but I'd been there scratching my head. Hope it helps.
Upvotes: 0
Reputation: 1181
You're probably making a mess with their routes.
It works like this:
form_for
calls @fashion_model.new_record?
IF True: It will submit to POST /fashion_model
, and create an object.
IF False: It will submit to PUT /fashion_model/:id
, and update an object.
As you can see, it just depends if the object already exists in the database or not. So, check again, where you are using the form_for
and which object you are passing it.
For questions with the routes, see: http://guides.rubyonrails.org/routing.html
Upvotes: 1