diff --git a/Gemfile.lock b/Gemfile.lock
index 12c121e0a..75fbd2e4f 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -819,7 +819,7 @@ GEM
rack-proxy (>= 0.6.1)
railties (>= 5.2)
semantic_range (>= 2.3.0)
- webrick (1.8.1)
+ webrick (1.8.2)
websocket-driver (0.7.6)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
diff --git a/app/models/article.rb b/app/models/article.rb
index 77903aeb7..b96333797 100644
--- a/app/models/article.rb
+++ b/app/models/article.rb
@@ -5,6 +5,7 @@
# id :bigint not null, primary key
# content :text
# description :text
+# locale :string default("en"), not null
# meta :jsonb
# position :integer
# slug :string not null
@@ -55,12 +56,14 @@ class Article < ApplicationRecord
# ensuring that the position is always set correctly
before_create :add_position_to_article
+ before_create :add_locale_to_article
after_save :category_id_changed_action, if: :saved_change_to_category_id?
enum status: { draft: 0, published: 1, archived: 2 }
scope :search_by_category_slug, ->(category_slug) { where(categories: { slug: category_slug }) if category_slug.present? }
scope :search_by_category_locale, ->(locale) { where(categories: { locale: locale }) if locale.present? }
+ scope :search_by_locale, ->(locale) { where(locale: locale) if locale.present? }
scope :search_by_author, ->(author_id) { where(author_id: author_id) if author_id.present? }
scope :search_by_status, ->(status) { where(status: status) if status.present? }
scope :order_by_updated_at, -> { reorder(updated_at: :desc) }
@@ -83,11 +86,11 @@ class Article < ApplicationRecord
)
def self.search(params)
- records = joins(
+ records = left_outer_joins(
:category
).search_by_category_slug(
params[:category_slug]
- ).search_by_category_locale(params[:locale]).search_by_author(params[:author_id]).search_by_status(params[:status])
+ ).search_by_locale(params[:locale]).search_by_author(params[:author_id]).search_by_status(params[:status])
records = records.text_search(params[:query]) if params[:query].present?
records
@@ -140,6 +143,14 @@ class Article < ApplicationRecord
update_article_position_in_category
end
+ def add_locale_to_article
+ self.locale = if category.present?
+ category.locale
+ else
+ portal.default_locale
+ end
+ end
+
def add_position_to_article
# on creation if a position is already present, ignore it
return if position.present?
diff --git a/app/views/public/api/v1/portals/show.html.erb b/app/views/public/api/v1/portals/show.html.erb
index 958848108..9e545776d 100644
--- a/app/views/public/api/v1/portals/show.html.erb
+++ b/app/views/public/api/v1/portals/show.html.erb
@@ -12,7 +12,7 @@
<%# Uncategorized articles %>
- <% if @portal.articles.where(status: :published, category_id: nil).count > 0 %>
+ <% if @portal.articles.where(status: :published, category_id: nil, locale: @locale).count > 0 %>
<%= render "public/api/v1/portals/uncategorized-block", category: "Uncategorized", portal: @portal %>
<% end %>
diff --git a/db/migrate/20240923215335_add_locale_to_article.rb b/db/migrate/20240923215335_add_locale_to_article.rb
new file mode 100644
index 000000000..28a335c83
--- /dev/null
+++ b/db/migrate/20240923215335_add_locale_to_article.rb
@@ -0,0 +1,24 @@
+class AddLocaleToArticle < ActiveRecord::Migration[7.0]
+ def change
+ add_column :articles, :locale, :string, default: 'en', null: false
+
+ set_locale_from_category
+ end
+
+ private
+
+ def set_locale_from_category
+ Article.find_in_batches do |article_batch|
+ article_batch.each do |article|
+ locale = if article.category.present?
+ article.category.locale
+ else
+ article.portal.default_locale
+ end
+ # rubocop:disable Rails/SkipsModelValidations
+ article.update_columns(locale: locale)
+ # rubocop:enable Rails/SkipsModelValidations
+ end
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 3ad9562b5..abb14d1e9 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema[7.0].define(version: 2024_07_26_220747) do
+ActiveRecord::Schema[7.0].define(version: 2024_09_23_215335) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_stat_statements"
enable_extension "pg_trgm"
@@ -147,6 +147,7 @@ ActiveRecord::Schema[7.0].define(version: 2024_07_26_220747) do
t.jsonb "meta", default: {}
t.string "slug", null: false
t.integer "position"
+ t.string "locale", default: "en", null: false
t.index ["associated_article_id"], name: "index_articles_on_associated_article_id"
t.index ["author_id"], name: "index_articles_on_author_id"
t.index ["slug"], name: "index_articles_on_slug", unique: true
diff --git a/spec/controllers/api/v1/accounts/articles_controller_spec.rb b/spec/controllers/api/v1/accounts/articles_controller_spec.rb
index 62380a5ee..754629b7b 100644
--- a/spec/controllers/api/v1/accounts/articles_controller_spec.rb
+++ b/spec/controllers/api/v1/accounts/articles_controller_spec.rb
@@ -194,6 +194,20 @@ RSpec.describe 'Api::V1::Accounts::Articles', type: :request do
expect(json_response['payload'].count).to be 2
end
+ it 'get all articles with uncategorized articles' do
+ article2 = create(:article, account_id: account.id, portal: portal, category: nil, locale: 'en', author_id: agent.id)
+ expect(article2.id).not_to be_nil
+
+ get "/api/v1/accounts/#{account.id}/portals/#{portal.slug}/articles",
+ headers: agent.create_new_auth_token,
+ params: {}
+ expect(response).to have_http_status(:success)
+ json_response = response.parsed_body
+ expect(json_response['payload'].count).to be 2
+ expect(json_response['payload'][0]['id']).to eq article2.id
+ expect(json_response['payload'][0]['category']['id']).to be_nil
+ end
+
it 'get all articles with searched params' do
article2 = create(:article, account_id: account.id, portal: portal, category: category, author_id: agent.id)
expect(article2.id).not_to be_nil
diff --git a/spec/factories/articles.rb b/spec/factories/articles.rb
index e68ed8f4b..e53549090 100644
--- a/spec/factories/articles.rb
+++ b/spec/factories/articles.rb
@@ -2,6 +2,7 @@ FactoryBot.define do
factory :article, class: 'Article' do
account_id { 1 }
category_id { 1 }
+ locale { 'en' }
author_id { 1 }
title { "#{Faker::Movie.title} #{SecureRandom.hex}" }
content { 'MyText' }
diff --git a/spec/models/article_spec.rb b/spec/models/article_spec.rb
index ff2734640..800f8fc9a 100644
--- a/spec/models/article_spec.rb
+++ b/spec/models/article_spec.rb
@@ -40,6 +40,25 @@ RSpec.describe Article do
end
end
+ describe 'add_locale_to_article' do
+ let(:portal) { create(:portal, config: { allowed_locales: %w[en es pt], default_locale: 'es' }) }
+ let(:category) { create(:category, slug: 'category_1', locale: 'pt', portal_id: portal.id) }
+
+ it 'adds locale to article from category' do
+ article = create(:article, category_id: category.id, content: 'This is the content', description: 'this is the description',
+ slug: 'this-is-title', title: 'this is title',
+ portal_id: portal.id, author_id: user.id)
+ expect(article.locale).to eq(category.locale)
+ end
+
+ it 'adds locale to article from portal' do
+ article = create(:article, content: 'This is the content', description: 'this is the description',
+ slug: 'this-is-title', title: 'this is title',
+ portal_id: portal.id, author_id: user.id)
+ expect(article.locale).to eq(portal.default_locale)
+ end
+ end
+
describe 'search' do
let!(:portal_2) { create(:portal, account_id: account.id, config: { allowed_locales: %w[en es] }) }
let!(:category_2) { create(:category, slug: 'category_2', locale: 'es', portal_id: portal_1.id) }