Compare commits

...

1 Commits

Author SHA1 Message Date
maddiebaka
937f97ecb2 Read-only patch written, frontend shows dictionary in different languages 2023-12-07 11:31:54 -05:00
23 changed files with 3364 additions and 264 deletions

View File

@ -23,7 +23,7 @@ gem "puma", ">= 5.0"
gem "importmap-rails" gem "importmap-rails"
# Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev] # Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev]
gem "turbo-rails" #gem "turbo-rails"
# Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev] # Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev]
gem "stimulus-rails" gem "stimulus-rails"

View File

@ -282,10 +282,6 @@ GEM
thor (1.2.2) thor (1.2.2)
tilt (2.3.0) tilt (2.3.0)
timeout (0.4.0) timeout (0.4.0)
turbo-rails (1.5.0)
actionpack (>= 6.0.0)
activejob (>= 6.0.0)
railties (>= 6.0.0)
tzinfo (2.0.6) tzinfo (2.0.6)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
unf (0.1.4) unf (0.1.4)
@ -328,7 +324,6 @@ DEPENDENCIES
sprockets-rails sprockets-rails
sqlite3 (~> 1.4) sqlite3 (~> 1.4)
stimulus-rails stimulus-rails
turbo-rails
tzinfo-data tzinfo-data
web-console web-console

View File

@ -3,6 +3,7 @@ class ActiveLanguageController < ApplicationController
def set_active_language def set_active_language
if Language.find_by_id(params[:active_language_id]) != nil if Language.find_by_id(params[:active_language_id]) != nil
cookies[:active_language_id] = params[:active_language_id] cookies[:active_language_id] = params[:active_language_id]
redirect_back fallback_location: root_path
else else
redirect_to root_path, status: :unprocessable_entity redirect_to root_path, status: :unprocessable_entity
end end

View File

@ -1,11 +1,19 @@
class DictionaryController < ApplicationController class DictionaryController < ApplicationController
def index def index
@parts_of_speech = PartOfSpeech.all @parts_of_speech = PartOfSpeech.where(language_id: active_language)
@words = Word.all @words = Word.all
end end
def show def show
@letter = params[:id] @letter = params[:id]
@words = Word.where('substr(word, 1, 1) = ?', @letter) @words = Word.where('substr(word, 1, 1) = ?', @letter)
@language = active_language
#@words.joins(:definitions).where(definitions: { language_id: active_language })
end
private
def active_language
cookies[:active_language_id] || Language.where(name: "English")
end end
end end

View File

@ -1,7 +1,8 @@
module ActiveLanguageHelper module ActiveLanguageHelper
def active_language_select_tag def active_language_select_tag
languages = Language.all.to_a.delete_if {|language| language.name == "English" } #languages = Language.all.to_a.delete_if {|language| language.name == "English" }
languages = Language.all.to_a
options = options_from_collection_for_select(languages, "id", "name", cookies[:active_language_id] || 1) options = options_from_collection_for_select(languages, "id", "name", cookies[:active_language_id] || 1)
select_tag "active_language_id", options, { id: "active_language_select_tag" } select_tag "active_language_id", options, { id: "active_language_select_tag" }
end end

View File

@ -1,5 +1,5 @@
// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails // Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
import "@hotwired/turbo-rails" //import "@hotwired/turbo-rails"
import "controllers" import "controllers"
let switchLanguageForm = document.querySelector("#active_language_form"); let switchLanguageForm = document.querySelector("#active_language_form");

View File

@ -1,3 +1,7 @@
class Word < ApplicationRecord class Word < ApplicationRecord
has_many :definitions has_many :definitions
def definitions_for(language)
self.definitions.where(language_id: language)
end
end end

View File

@ -1,12 +1,12 @@
<table> <table>
<tr> <tr>
<td><b>Part of Speech</b></td> <td class="px-2"><b>Part of Speech</b></td>
<td><b>Definition</b></td> <td class="px-2"><b>Definition</b></td>
</tr> </tr>
<% word.definitions.each do |definition| %> <% word.definitions_for(language).each do |definition| %>
<tr> <tr>
<td><b><%= definition.pos %></b></td> <td class="px-2"><b><%= definition.pos %></b></td>
<td><%= definition.definition %></td> <td class="px-2"><%= definition.definition %></td>
</tr> </tr>
<% end %> <% end %>
</table> </table>

View File

@ -2,13 +2,13 @@
<table> <table>
<tr> <tr>
<td><b>Part of Speech</b></td> <td class="px-2"><b>Part of Speech</b></td>
<td><b>Definition</b></td> <td class="px-2"><b>Definition</b></td>
</tr> </tr>
<% parts_of_speech.each do |item| %> <% parts_of_speech.each do |item| %>
<tr> <tr>
<td><b><%= item.pos %></b></td> <td class="px-2"><b><%= item.pos %></b></td>
<td><%= item.definition %></td> <td class="px-2"><%= item.definition %></td>
</tr> </tr>
<% end %> <% end %>
</table> </table>

View File

@ -7,6 +7,6 @@
<% @words.each do |word| %> <% @words.each do |word| %>
<div class="dictionary-entry p-4"> <div class="dictionary-entry p-4">
<h2><%= word.word %></h2> <h2><%= word.word %></h2>
<%= render "definitions", word: word %> <%= render "definitions", word: word, language: @language %>
</div> </div>
<% end %> <% end %>

View File

@ -23,25 +23,9 @@
<div class="d-flex mb-3"> <div class="d-flex mb-3">
<div class="p-2"> <div class="p-2">
<%= link_to "Dictionary", dictionary_index_path %> <%= link_to "Dictionary", dictionary_index_path %>
<% if user_signed_in? %> <%= form_tag '/set_active_language', class: 'd-inline', id: 'active_language_form' do %>
<pre style="display: inline;">|</pre> <%= active_language_select_tag %>
<%= link_to "Languages", admin_languages_path %> <%= submit_tag "Switch Language", id: "active_language_submit_tag" %>
<pre style="display: inline;">|</pre>
<%= form_tag '/set_active_language', class: "d-inline", id: "active_language_form" do %>
<%= active_language_select_tag %>
<%= submit_tag "Switch Language", id: "active_language_submit_tag" %>
<% end %>
<% end %>
</div>
<div class="ms-auto p-2">
<% if user_signed_in? %>
<p style="display: inline;">Welcome <%= current_user.username %></p>
<pre style="display: inline;">|</pre>
<%= link_to "Sign Out", destroy_user_session_path, data: { turbo_method: :delete } %>
<% else %>
<%= link_to "Sign In", new_user_session_path %>
<pre style="display: inline;">|</pre>
<%= link_to "Register", new_user_registration_path %>
<% end %> <% end %>
</div> </div>
</div> </div>

View File

@ -1,19 +1,19 @@
Rails.application.routes.draw do Rails.application.routes.draw do
devise_for :users #devise_for :users
#get 'dictionary/index' #get 'dictionary/index'
resources :dictionary, only: [:index, :show, :create] resources :dictionary, only: [:index, :show, :create]
resources :words, only: [:index, :show] #resources :words, only: [:index, :show]
post '/set_active_language', action: :set_active_language, controller: :active_language post '/set_active_language', action: :set_active_language, controller: :active_language
namespace :admin do #namespace :admin do
resources :languages # resources :languages
end #end
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
# Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500. # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500.
# Can be used by load balancers and uptime monitors to verify that the app is live. # Can be used by load balancers and uptime monitors to verify that the app is live.
get "up" => "rails/health#show", as: :rails_health_check #get "up" => "rails/health#show", as: :rails_health_check
# Defines the root path route ("/") # Defines the root path route ("/")
# root "posts#index" # root "posts#index"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,46 @@
[
{
"pos": "n",
"definition": "nom principal"
},
{
"pos": "mod",
"definition": "modificateur (adjectif ou adverbe)"
},
{
"pos": "sep",
"definition": "séparateur"
},
{
"pos": "vt",
"definition": "verbe transitif (généralement utilisé avec \"e\")"
},
{
"pos": "vi",
"definition": "verbe intransitif"
},
{
"pos": "interj",
"definition": "interjection"
},
{
"pos": "prep",
"definition": "quasi-préposition"
},
{
"pos": "conj",
"definition": "conjonction"
},
{
"pos": "kama",
"definition": "verbe composé précédé de \"kama\""
},
{
"pos": "cont",
"definition": "mot de contexte utilisé avant \"la\""
},
{
"pos": "oth",
"definition": "mot spécial, autre"
}
]

View File

@ -1,30 +1,33 @@
namespace :dataset do namespace :dataset do
desc "TODO" desc "TODO"
task ingest: :environment do task ingest: :environment do
english = create_english_lang english = create_language('English')
ingest_pos(english) ingest_pos(english, 'dataset_en')
ingest_dictionary(english) ingest_dictionary(english, 'dataset_en')
french = create_language('French')
ingest_pos(french, 'dataset_fr')
ingest_dictionary(french, 'dataset_fr')
puts "Ingest complete." puts "Ingest complete."
end end
end end
def create_english_lang def create_language(name)
if Language.count > 0 if Language.where(name: name).count > 0
puts "Language English already exists! Skipping step." puts "Language #{name} already exists! Skipping step."
return return
end end
return Language.create(name: "English") return Language.create(name: name)
end end
def ingest_pos(language) def ingest_pos(language, dataset)
if PartOfSpeech.count > 0 if PartOfSpeech.where(language_id: language.id).count > 0
puts "Parts of speech data already exists in table! Aborting." puts "Parts of speech data already exists in table! Aborting."
return return
end end
parts_of_speech = JSON.parse(File.read('db/dataset_en/toki-partsofspeech.json')) parts_of_speech = JSON.parse(File.read("db/#{dataset}/toki-partsofspeech.json"))
parts_of_speech.each do |pos| parts_of_speech.each do |pos|
PartOfSpeech.create(pos: pos['pos'], definition: pos['definition'], language_id: language.id) PartOfSpeech.create(pos: pos['pos'], definition: pos['definition'], language_id: language.id)
@ -32,19 +35,24 @@ def ingest_pos(language)
puts "Parts of speech ingest complete." puts "Parts of speech ingest complete."
end end
def ingest_dictionary(language) def ingest_dictionary(language, dataset)
if Word.count > 0 if Definition.where(language_id: language.id).count > 0
puts "Dictionary data already exists in table! Aborting." puts "Dictionary data for this language already exists in table! Aborting."
return return
end end
dictionary = JSON.parse(File.read('db/dataset_en/toki-dictionary.json')) dictionary = JSON.parse(File.read("db/#{dataset}/toki-dictionary.json"))
dictionary.each do |entry| dictionary.each do |entry|
if entry['word'] == "a" if entry['word'] == "a"
puts entry puts entry
end end
word = Word.create(word: entry['word']) #word = Word.create(word: entry['word'])
word = Word.where(word: entry['word']).first
if word.nil?
word = Word.create(word: entry['word'])
end
entry['definitions'].each do |definition| entry['definitions'].each do |definition|
word.definitions.create(pos: definition['pos'], definition: definition['definition'], language_id: language.id) word.definitions.create(pos: definition['pos'], definition: definition['definition'], language_id: language.id)

View File

@ -1,22 +0,0 @@
require 'rails_helper'
RSpec.describe WordsController, type: :controller do
describe "GET :index" do
it 'renders the index template' do
get :index
expect(response).to render_template(:index)
end
it 'sets @words instance variable' do
FactoryBot.create(:word)
get :index
expect(assigns(:words)).to be_a(ActiveRecord::Relation)
end
it 'fetches all words into @words' do
5.times { FactoryBot.create(:word) }
get :index
expect(assigns(:words).count).to eq(5)
end
end
end

View File

@ -1,7 +1,7 @@
FactoryBot.define do FactoryBot.define do
factory :part_of_speech do factory :part_of_speech do
sequence(:pos) { |n| "test-#{n.to_s}" } sequence(:pos) { |n| "test-#{n.to_s}" }
language_id { FactoryBot.create(:language).id } language_id { FactoryBot.create(:language_english).id }
definition { "test definition" } definition { "test definition" }
end end
end end

View File

@ -23,10 +23,6 @@ RSpec.describe ActiveLanguageHelper, type: :helper do
expect(@tag).to have_selector(%(select)) expect(@tag).to have_selector(%(select))
end end
it "should not contain an English option" do
expect(@tag).to_not include("English")
end
it "should include css id #active_language_select_tag" do it "should include css id #active_language_select_tag" do
expect(@tag).to have_selector(%(select[id="active_language_select_tag"])) expect(@tag).to have_selector(%(select[id="active_language_select_tag"]))
end end

View File

@ -14,6 +14,7 @@ RSpec.describe "Dictionary", type: :request do
it "shows the count of parts of speech in the database" do it "shows the count of parts of speech in the database" do
5.times { FactoryBot.create(:part_of_speech) } 5.times { FactoryBot.create(:part_of_speech) }
#puts PartOfSpeech.count
get "/dictionary" get "/dictionary"
expect(response.body).to include("#{PartOfSpeech.count} parts of speech entries in database") expect(response.body).to include("#{PartOfSpeech.count} parts of speech entries in database")
end end

View File

@ -1,106 +0,0 @@
require 'rails_helper'
RSpec.describe "Languages", type: :request do
describe "GET :index" do
it "returns http success" do
get "/admin/languages/"
expect(response).to have_http_status(:success)
end
it "lists all languages" do
language = FactoryBot.create(:language)
get "/admin/languages/"
expect(response.body).to include(language.name)
end
it "has a new-language link" do
get "/admin/languages/"
expect(response.body).to have_selector(%(a[href="#{new_admin_language_path}"]))
end
it "has an edit button" do
language = FactoryBot.create(:language)
get "/admin/languages/"
expect(response.body).to have_link("Edit")
end
it "has a delete button" do
language = FactoryBot.create(:language)
get "/admin/languages/"
expect(response.body).to have_link("Delete")
end
end
describe "GET :new" do
it "returns http success" do
get "/admin/languages/new"
expect(response).to have_http_status(:success)
end
it "has a form for a new language" do
get "/admin/languages/new"
expect(response.body).to have_selector(%(input[name="language[name]"]))
end
end
describe "POST :create" do
it "redirect to admin_languages_path on success" do
post "/admin/languages", params: { language: { name: "Test Name" } }
expect(response).to redirect_to(admin_languages_path)
end
it "creates a new language" do
post "/admin/languages", params: { language: { name: "Test Name" } }
expect(Language.count).to eq(1)
end
it "requires a name for a new language" do
post "/admin/languages", params: { language: { name: nil } }
expect(response).to have_http_status(:unprocessable_entity)
end
end
describe "GET :edit" do
before :each do
@language = FactoryBot.create(:language)
get "/admin/languages/#{@language.id}/edit"
end
it "returns http success" do
expect(response).to have_http_status(:success)
end
it "has a form to edit language" do
expect(response.body).to have_selector(%(input[name="language[name]"]))
end
end
describe "PATCH :update" do
before :each do
@language = FactoryBot.create(:language)
@params = { language: { name: "Test Name Update" } }
end
it "updates a language" do
patch "/admin/languages/#{@language.id}", params: @params
expect(response).to redirect_to(admin_languages_path)
end
it "requires params to update a language" do
@params = { language: { name: nil, invalid: "oh no" } }
patch "/admin/languages/#{@language.id}", params: @params
expect(response).to have_http_status(:unprocessable_entity)
end
end
describe "DELETE :destroy" do
it "deletes a language" do
language = FactoryBot.create(:language)
language2 = FactoryBot.create(:language)
delete "/admin/languages/#{language.id}"
expect(Language.all).to eq([language2])
end
end
end

View File

@ -13,38 +13,8 @@ RSpec.describe "Root path", type: :request do
end end
end end
describe "logged out" do it "should have a language drop-down" do
it "should have 'Register' link" do get root_path
get root_path expect(response.body).to have_field("active_language_id")
expect(response.body).to include("Register")
end
end
describe "logged in" do
it "should have 'Sign Out' link" do
sign_in FactoryBot.create(:user)
get root_path
expect(response.body).to include("Sign Out")
end
it "should have the 'Languages' link" do
sign_in FactoryBot.create(:user)
get root_path
expect(response.body).to have_selector(%(a[href="#{admin_languages_path}"]))
end
it "should welcome user by username" do
user = FactoryBot.create(:user)
sign_in user
get root_path
expect(response.body).to include(user.username)
end
it "should have a language drop-down" do
user = FactoryBot.create(:user)
sign_in user
get root_path
expect(response.body).to have_field("active_language_id")
end
end end
end end

View File

@ -1,39 +0,0 @@
require 'rails_helper'
RSpec.describe "Words", type: :request do
describe "GET /index" do
it "renders the index template" do
get "/words"
expect(response).to render_template(:index)
end
end
describe "GET /show/:val" do
before(:each) do
@word = FactoryBot.create(:word)
end
it "renders the show template" do
get "/words/#{@word.id}"
expect(response).to render_template(:show)
end
it "sets @word instance variable" do
get "/words/#{@word.id}"
expect(assigns(:word)).to be_a(Word)
end
it "displays the word name" do
get "/words/#{@word.id}"
expect(response.body).to include(@word.word)
end
it "displays the definitions" do
@definition = FactoryBot.create(:definition)
get "/words/#{@definition.word_id}"
expect(response.body).to include(@definition.definition)
end
end
end