Reputation: 15028
I have three models, Artwork
, ArtworkTag
, and Tag
, where ArtworkTag
represents an m:n relation between Artwork
and Tag
. Tag
only stores the tag name, i.e. :tag
.
When creating tags from ArtworkTagsController
, it's necessary to first see if the :tag
exists in the tags
table, create it if not, and then use the tag id
to make the relation in ArtworkTag
.
Below you can see that I'm calling Tag
directly from this controller, which I don't think is the right practice.
How should I be handling this situation with the proper separation of concerns?
def create
tag = params[:artwork_tag][:tag].downcase
@tag = Tag.find_by_tag(tag)
if @tag.blank?
@tag = Tag.new(:tag => tag)
@tag.save
end
artwork_id = params[:artwork_tag][:artwork_id]
user_id = params[:artwork_tag][:user_id]
artwork_tag = {
"tag_id" => @tag.id,
"artwork_id" => artwork_id,
"user_id" => user_id
}
@artwork_tag = ArtworkTag.new(:tag_id => @tag.id, :artwork_id => artwork_id, :user_id => user_id)
@artwork_tag.save
respond_to do |format|
format.json { render :json => {
"id" => @artwork_tag.id, "tag" => @tag.tag, "artwork_id" => artwork_id },
:status => :created }
end
end
Upvotes: 0
Views: 77
Reputation: 45094
I would do something like this:
def create
artwork_tag = ArtworkTag.create(
:tag => Tag.find_or_create_by_tag(params[:artwork_tag][:tag].downcase),
:artwork_id => params[:artwork_tag][:artwork_id],
:user_id => params[:artwork_tag][:user_id]
)
respond_to do |format|
format.json { render :json => { :artwork_tag => artwork_tag } }
end
end
Upvotes: 1
Reputation: 8604
I'm not sure I understand your question, but you can use first_or_create
method to check if record is already exists or not, if not it will create new record. You can replace this:
@tag = Tag.find_by_tag(tag)
if @tag.blank?
@tag = Tag.new(:tag => tag)
@tag.save
end
with only one row: (I'm not use instance variable because i think you don't need use it in view, if you need just change it to @tag
and in params to tag_id: @tag.id
)
tag = Tag.where(tag: tag).first_or_create()
I see you defined artwork_tag
, but why you aren't use it? I think you can replace:
artwork_tag = {
"tag_id" => @tag.id,
"artwork_id" => artwork_id,
"user_id" => user_id
}
@artwork_tag = ArtworkTag.new(:tag_id => @tag.id, :artwork_id => artwork_id, :user_id => user_id)
@artwork_tag.save
with this code:
params = { artwork_tag: {
tag_id: tag.id,
artwork_id: artwork_id,
user_id: user_id } }
@artwork_tag = ArtworkTag.create(params[:artwork_tag])
Upvotes: 0