I am using Ruby on Rails 4 and I would like to properly handle the updating and creating process of associated records through the update_attributes
method. That is, I have the following:
# Model
class Article < ActiveRecord::Base
has_many :categories
accepts_nested_attributes_for :categories
end
# Controller
class ArticlesController < ApplicationController
def update
@article = Article.find(params[:id])
@article.update_attributes(update_params)
...
end
private
def update_params
params.require(:article).permit(:title, ..., :categories_attributes => [:name, ...])
end
end
# Logger for the update request
Started PATCH "/articles/6"
Processing by ArticlesController#update
Parameters: {"utf8"=>"✓", "article"=>{"title"=>"Sample title", "categories_attributes"=>{"0"=>{"name"=>"Sample Category 1", "..."=>"..."}, "1"=>{"name"=>"Sample Category 2", "..."=>"..."}, : "..." => {...}}
...
The issue is related to the way Rails handles things for updating associated records in the database, in my case when updating categories through the @article
object: when data is submitted so to fire the update
action and parameters are passed to the update_attributes
method (as shown in the logger above) then Rails creates new category records in the database, one for each element present in the hash categories_attributes
.
However, my intention is to update existing category records if those exist or create new ones if those do not exist, accordingly to the uniqueness of article_id
and name
columns in the categories
database table, probabily performing a search for data present in these columns in order to check if it is needed to update or create new records. In fact, in the "edit article" view I display a form with input fields for editing categories including fields pre-populated with data related to existing categories and empty fields for categories that can be created "on the fly" by the editor user.
How can I properly handle this behavior? Is it model or controller responsability? Or, maybe, is there a better way to manage categories directly in the "edit article" view?