Fix related content with custom URLs
Some CONSUL installations might want to customize their URLs. For instance, Spanish institutions might want to use "/propuestas" instead of "/proposals". In that case, it would be impossible to add proposals as related content because the related contents controller assumed the name of the model was part of the URL. Using `recognize_path` instead of manually analyzing the URL solves the issue. Now that we don't call the `constantize` method on an empty string as we previously did, we can be more specific in the `rescue` block and point out that the only exception we expect is the one where users enter a route which isn't recognized.
This commit is contained in:
@@ -7,7 +7,8 @@ class RelatedContentsController < ApplicationController
|
||||
related_content = current_user.related_contents.new(
|
||||
parent_relationable_id: params[:relationable_id],
|
||||
parent_relationable_type: params[:relationable_klass],
|
||||
child_relationable: related_object
|
||||
child_relationable_id: child_relationable_params[:id],
|
||||
child_relationable_type: child_relationable_params[:type]
|
||||
)
|
||||
|
||||
if related_content.save
|
||||
@@ -41,17 +42,23 @@ class RelatedContentsController < ApplicationController
|
||||
params[:url].start_with?(Setting["url"])
|
||||
end
|
||||
|
||||
def related_object
|
||||
if valid_url?
|
||||
url = params[:url]
|
||||
def child_relationable_params
|
||||
@child_relationable_params ||=
|
||||
if valid_url?
|
||||
related_params = Rails.application.routes.recognize_path(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
|
||||
if RelatedContent::RELATIONABLE_MODELS.include?(related_params[:controller].split("/").last)
|
||||
{
|
||||
id: related_params[:id],
|
||||
type: related_params[:controller].split("/").map(&:singularize).join("/").classify
|
||||
}
|
||||
else
|
||||
{}
|
||||
end
|
||||
else
|
||||
{}
|
||||
end
|
||||
rescue ActionController::RoutingError
|
||||
{}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -90,6 +90,33 @@ shared_examples "relationable" do |relationable_model_name|
|
||||
expect(page).to have_content "Link not valid. You cannot relate a content to itself"
|
||||
end
|
||||
|
||||
context "custom URLs" do
|
||||
before do
|
||||
custom_route = proc { get "/mypath/:id" => "debates#show" }
|
||||
Rails.application.routes.send(:eval_block, custom_route)
|
||||
end
|
||||
|
||||
after { Rails.application.reload_routes! }
|
||||
|
||||
scenario "finds relationable with custom URLs" do
|
||||
related = create(:debate, title: "My path is the only one I've walked")
|
||||
|
||||
login_as(user)
|
||||
visit relationable.url
|
||||
|
||||
click_button "Add related content"
|
||||
|
||||
within("#related_content") do
|
||||
fill_in "Link to related content", with: "#{url}/mypath/#{related.id}"
|
||||
click_button "Add"
|
||||
end
|
||||
|
||||
within("#related-content-list") do
|
||||
expect(page).to have_content "My path is the only one I've walked"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
scenario "related content can be scored positively" do
|
||||
related_content = create(:related_content, parent_relationable: relationable, child_relationable: related1, author: build(:user))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user