mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-30 10:58:31 -05:00
FIX: Clashing category slug.
This commit is contained in:
parent
65e808b26d
commit
c60e360c90
10 changed files with 65 additions and 14 deletions
|
@ -255,7 +255,7 @@ export default Ember.Component.extend({
|
||||||
template: template,
|
template: template,
|
||||||
key: '#',
|
key: '#',
|
||||||
transformComplete(category) {
|
transformComplete(category) {
|
||||||
return category.get('slug');
|
return Category.slugFor(category, ":");
|
||||||
},
|
},
|
||||||
dataSource(term) {
|
dataSource(term) {
|
||||||
return Category.search(term);
|
return Category.search(term);
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
**/
|
**/
|
||||||
Discourse.Dialect.inlineRegexp({
|
Discourse.Dialect.inlineRegexp({
|
||||||
start: '#',
|
start: '#',
|
||||||
matcher: /^#([\w-]{1,50})/i,
|
matcher: /^#([\w-:]{1,50})/i,
|
||||||
spaceOrTagBoundary: true,
|
spaceOrTagBoundary: true,
|
||||||
|
|
||||||
emitter: function(matches) {
|
emitter: function(matches) {
|
||||||
|
|
|
@ -205,14 +205,14 @@ Category.reopenClass({
|
||||||
return _uncategorized;
|
return _uncategorized;
|
||||||
},
|
},
|
||||||
|
|
||||||
slugFor(category) {
|
slugFor(category, separator = "/") {
|
||||||
if (!category) return "";
|
if (!category) return "";
|
||||||
|
|
||||||
const parentCategory = Em.get(category, 'parentCategory');
|
const parentCategory = Em.get(category, 'parentCategory');
|
||||||
let result = "";
|
let result = "";
|
||||||
|
|
||||||
if (parentCategory) {
|
if (parentCategory) {
|
||||||
result = Category.slugFor(parentCategory) + "/";
|
result = Category.slugFor(parentCategory) + separator;
|
||||||
}
|
}
|
||||||
|
|
||||||
const id = Em.get(category, 'id'),
|
const id = Em.get(category, 'id'),
|
||||||
|
|
|
@ -5,8 +5,10 @@ class CategoryHashtagsController < ApplicationController
|
||||||
category_slugs = params[:category_slugs]
|
category_slugs = params[:category_slugs]
|
||||||
category_slugs.each(&:downcase!)
|
category_slugs.each(&:downcase!)
|
||||||
|
|
||||||
valid_categories = Category.secured(guardian).where(slug: category_slugs).map do |category|
|
ids = category_slugs.map { |category_slug| Category.query_from_hashtag_slug(category_slug).try(:id) }
|
||||||
{ slug: category.slug, url: category.url_with_id }
|
|
||||||
|
valid_categories = Category.secured(guardian).where(id: ids).map do |category|
|
||||||
|
{ slug: category.hashtag_slug, url: category.url_with_id }
|
||||||
end.compact
|
end.compact
|
||||||
|
|
||||||
render json: { valid: valid_categories }
|
render json: { valid: valid_categories }
|
||||||
|
|
|
@ -5,6 +5,7 @@ class Category < ActiveRecord::Base
|
||||||
|
|
||||||
include Positionable
|
include Positionable
|
||||||
include HasCustomFields
|
include HasCustomFields
|
||||||
|
include CategoryHashtag
|
||||||
|
|
||||||
belongs_to :topic, dependent: :destroy
|
belongs_to :topic, dependent: :destroy
|
||||||
belongs_to :topic_only_relative_url,
|
belongs_to :topic_only_relative_url,
|
||||||
|
@ -398,8 +399,8 @@ SQL
|
||||||
@@url_cache.clear
|
@@url_cache.clear
|
||||||
end
|
end
|
||||||
|
|
||||||
def full_slug
|
def full_slug(separator = "-")
|
||||||
url[3..-1].gsub("/", "-")
|
url[3..-1].gsub("/", separator)
|
||||||
end
|
end
|
||||||
|
|
||||||
def url
|
def url
|
||||||
|
|
23
app/models/concerns/category_hashtag.rb
Normal file
23
app/models/concerns/category_hashtag.rb
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
module CategoryHashtag
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
SEPARATOR = ":".freeze
|
||||||
|
|
||||||
|
class_methods do
|
||||||
|
def query_from_hashtag_slug(category_slug)
|
||||||
|
parent_slug, child_slug = category_slug.split(":", 2)
|
||||||
|
|
||||||
|
category = Category.where(slug: parent_slug, parent_category_id: nil)
|
||||||
|
|
||||||
|
if child_slug
|
||||||
|
Category.where(slug: child_slug, parent_category_id: category.pluck(:id).first).first
|
||||||
|
else
|
||||||
|
category.first
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def hashtag_slug
|
||||||
|
full_slug(SEPARATOR)
|
||||||
|
end
|
||||||
|
end
|
|
@ -49,9 +49,8 @@ module PrettyText
|
||||||
end
|
end
|
||||||
|
|
||||||
def category_hashtag_lookup(category_slug)
|
def category_hashtag_lookup(category_slug)
|
||||||
if category_slug
|
if category = Category.query_from_hashtag_slug(category_slug)
|
||||||
category = Category.find_by_slug(category_slug)
|
['category', category.url_with_id]
|
||||||
return ['category', category.url_with_id] if category
|
|
||||||
else
|
else
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
26
spec/components/concern/category_hashtag_spec.rb
Normal file
26
spec/components/concern/category_hashtag_spec.rb
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
describe CategoryHashtag do
|
||||||
|
describe '#query_from_hashtag_slug' do
|
||||||
|
let(:parent_category) { Fabricate(:category) }
|
||||||
|
let(:child_category) { Fabricate(:category, parent_category: parent_category) }
|
||||||
|
|
||||||
|
it "should return the right result for a parent category slug" do
|
||||||
|
expect(Category.query_from_hashtag_slug(parent_category.slug))
|
||||||
|
.to eq(parent_category)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return the right result for a parent and child category slug" do
|
||||||
|
expect(Category.query_from_hashtag_slug("#{parent_category.slug}:#{child_category.slug}"))
|
||||||
|
.to eq(child_category)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return nil for incorrect parent category slug" do
|
||||||
|
expect(Category.query_from_hashtag_slug("random-slug")).to eq(nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return nil for incorrect parent and child category slug" do
|
||||||
|
expect(Category.query_from_hashtag_slug("random-slug:random-slug")).to eq(nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -390,7 +390,7 @@ HTML
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't replace unicode emoji if emoji is disabled" do
|
it "doesn't replace unicode emoji if emoji is disabled" do
|
||||||
SiteSetting.enable_emoji = false
|
SiteSetting.enable_emoji = false
|
||||||
expect(PrettyText.cook("💣")).not_to match(/\:bomb\:/)
|
expect(PrettyText.cook("💣")).not_to match(/\:bomb\:/)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,7 +12,7 @@ describe CategoryHashtagsController do
|
||||||
xhr :get, :check, category_slugs: [category.slug, 'none']
|
xhr :get, :check, category_slugs: [category.slug, 'none']
|
||||||
|
|
||||||
expect(JSON.parse(response.body)).to eq(
|
expect(JSON.parse(response.body)).to eq(
|
||||||
{ "valid" => [{ "slug" => category.slug, "url" => category.url_with_id }] }
|
{ "valid" => [{ "slug" => category.hashtag_slug, "url" => category.url_with_id }] }
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ describe CategoryHashtagsController do
|
||||||
xhr :get, :check, category_slugs: [private_category.slug]
|
xhr :get, :check, category_slugs: [private_category.slug]
|
||||||
|
|
||||||
expect(JSON.parse(response.body)).to eq(
|
expect(JSON.parse(response.body)).to eq(
|
||||||
{ "valid" => [{ "slug" => private_category.slug, "url" => private_category.url_with_id }] }
|
{ "valid" => [{ "slug" => private_category.hashtag_slug, "url" => private_category.url_with_id }] }
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue