Add languages to User model (#20059)

This commit is contained in:
Anna Buianova 2023-09-11 18:44:19 +03:00 committed by GitHub
parent e1c91d2a64
commit aa5cb535fa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 66 additions and 1 deletions

View file

@ -115,6 +115,8 @@ class User < ApplicationRecord
has_many :subscribers, through: :source_authored_user_subscriptions, dependent: :destroy
has_many :tweets, dependent: :nullify
has_many :devices, dependent: :delete_all
# languages that user undestands
has_many :languages, class_name: "UserLanguage", inverse_of: :user, dependent: :delete_all
mount_uploader :profile_image, ProfileImageUploader

View file

@ -0,0 +1,5 @@
class UserLanguage < ApplicationRecord
belongs_to :user, inverse_of: :languages
validates :language, inclusion: { in: Languages::Detection.codes }, presence: true
end

View file

@ -4,6 +4,10 @@ module Languages
PROBABILITY_THRESHOLD = 0.5
def self.codes
CLD3::TaskContextParams::LANGUAGE_NAMES.map(&:to_s).freeze
end
def self.call(...)
new(...).call
end

View file

@ -0,0 +1,10 @@
class CreateUserLanguages < ActiveRecord::Migration[7.0]
def change
create_table :user_languages do |t|
t.references :user, foreign_key: true, null: false
t.string :language, null: false
t.timestamps
end
end
end

View file

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.0].define(version: 2023_08_31_160030) do
ActiveRecord::Schema[7.0].define(version: 2023_09_06_112602) do
# These are extensions that must be enabled in order to support this database
enable_extension "citext"
enable_extension "ltree"
@ -1187,6 +1187,14 @@ ActiveRecord::Schema[7.0].define(version: 2023_08_31_160030) do
t.index ["blocked_id", "blocker_id"], name: "index_user_blocks_on_blocked_id_and_blocker_id", unique: true
end
create_table "user_languages", force: :cascade do |t|
t.datetime "created_at", null: false
t.string "language", null: false
t.datetime "updated_at", null: false
t.bigint "user_id", null: false
t.index ["user_id"], name: "index_user_languages_on_user_id"
end
create_table "user_subscriptions", force: :cascade do |t|
t.bigint "author_id", null: false
t.datetime "created_at", null: false
@ -1454,6 +1462,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_08_31_160030) do
add_foreign_key "tweets", "users", on_delete: :nullify
add_foreign_key "user_blocks", "users", column: "blocked_id"
add_foreign_key "user_blocks", "users", column: "blocker_id"
add_foreign_key "user_languages", "users"
add_foreign_key "user_subscriptions", "users", column: "author_id"
add_foreign_key "user_subscriptions", "users", column: "subscriber_id"
add_foreign_key "users_notification_settings", "users"

View file

@ -0,0 +1,6 @@
FactoryBot.define do
factory :user_language do
user
language { :en }
end
end

View file

@ -0,0 +1,22 @@
require "rails_helper"
RSpec.describe UserLanguage do
describe "validations" do
subject { build(:user_language) }
describe "builtin validations" do
it { is_expected.to belong_to(:user) }
it { is_expected.to validate_presence_of(:language) }
end
it "actually validates language" do
expect(build(:user_language, language: :es)).to be_valid
end
it "actually validates language (invalid)" do
lang = build(:user_language, language: :abracadabra)
expect(lang).not_to be_valid
expect(lang.errors[:language]).to be_present
end
end
end

View file

@ -112,6 +112,7 @@ RSpec.describe User do
it { is_expected.to have_many(:subscribed_to_user_subscriptions).dependent(:destroy) }
it { is_expected.to have_many(:subscribers).dependent(:destroy) }
it { is_expected.to have_many(:tweets).dependent(:nullify) }
it { is_expected.to have_many(:languages).dependent(:delete_all) }
# rubocop:disable RSpec/NamedSubject
it do

View file

@ -3,6 +3,12 @@ require "rails_helper"
RSpec.describe Languages::Detection, type: :service do
subject(:language_detection) { described_class.call(text) }
describe "codes" do
it "returns an array including a couple of popular languages" do
expect(described_class.codes).to include("en", "es", "fr")
end
end
context "when the text is clearly identifiable as English" do
let(:text) { "This is clearly English text." }