Files
grecia/app/controllers/related_contents_controller.rb
Javi Martín 8f20ee1a33 Move related content validation to the model
We were manually checking validation rules (like both relationable
objects are present, or they're both the same object) in the controller
and then using the `save!` method.

However, we usually use the `save` method (which checks all validations)
in a condition, and proceed depending on the result.

Now we're taking the same approach here. This means introducing a new
validation rule in the model to check whether both relationable objects
are the same, which is more robust than checking a condition in the
controller.
2021-06-23 23:13:58 +02:00

62 lines
1.6 KiB
Ruby

class RelatedContentsController < ApplicationController
skip_authorization_check
respond_to :html, :js
def create
related_content = RelatedContent.new(
parent_relationable: relationable_object,
child_relationable: related_object,
author: current_user
)
if related_content.save
flash[:success] = t("related_content.success")
elsif related_content.same_parent_and_child?
flash[:error] = t("related_content.error_itself")
else
flash[:error] = t("related_content.error", url: Setting["url"])
end
redirect_to polymorphic_path(relationable_object)
end
def score_positive
score(:positive)
end
def score_negative
score(:negative)
end
private
def score(action)
@related = RelatedContent.find params[:id]
@related.send("score_#{action}", current_user)
render template: "relationable/_refresh_score_actions"
end
def valid_url?
params[:url].start_with?(Setting["url"])
end
def relationable_object
@relationable ||= params[:relationable_klass].singularize.camelize.constantize.find_by(id: params[:relationable_id])
end
def related_object
if valid_url?
url = params[:url]
related_klass = url.scan(/\/(#{RelatedContent::RELATIONABLE_MODELS.join("|")})\//)
.flatten.map { |i| i.to_s.singularize.camelize }.join("::")
related_id = url.match(/\/(\d+)(?!.*\/\d)/)[1]
related_klass.singularize.camelize.constantize.find_by(id: related_id)
end
rescue
nil
end
end