Reputation: 1368
I'm currently working on a simple Rails 4 app where I have these two related models:
book.rb
class Book < ActiveRecord::Base
belongs_to :author
accepts_nested_attributes_for :author
end
author.rb
class Author < ActiveRecord::Base
has_many :books
end
What I need to do is to check if the author exists already and if it does, use it on the book.
My books_controller.rb
class BooksController < ApplicationController
.
.
.
def create
@book = Book.new(BookParams.build(params)) # Uses class for strong params
if @book.save
redirect_to @book, notice: t('alerts.success')
else
render action: 'new'
end
end
end
Is there a better way to deal with this scenario without having duplicate author records? Thank you.
Upvotes: 1
Views: 2364
Reputation: 1368
I've managed to make it work by using the code below:
models/book.rb
def author_attributes=(value)
self.author = Author.find_or_create_by(value)
end
Upvotes: 0
Reputation: 33626
You can do this using a before_save
callback in the Book
model:
class Book < ActiveRecord::Base
# ...
before_save :merge_author
private
def merge_author
if (author = Author.find_by(name: self.author.name))
self.author = author
end
end
end
Note here that I am assuming here that your Author
model has a name
field which identifies each author. Perhaps you want to have another mechanism to determine if the author already exists.
However, Active Record Validations can also help you ensure that you have no duplicated records in your Author
model.
Upvotes: 3
Reputation: 135
I might be misunderstanding but try to clearify the problem a little more please.
From my point of view you have to make sure yourself that you don't have duplicate records. In Rails you can use Validations in that case.
On the other hand what you are trying to solve looks like building/creating an ActiveRecord object through an ActiveRecord association. You have a Rails way for that, too.
Next there a callbacks, nested routes/controllers aso that fit to different requirements. You find Rails Guides for them, too. Of course it can be a combination of everything =) And you have nested attributes as well which might have to be considered. cheers
Upvotes: 0