Add Language model and LanguageController
This commit is contained in:
parent
ed00e69a13
commit
206c4da31f
50
app/controllers/languages_controller.rb
Normal file
50
app/controllers/languages_controller.rb
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
class LanguagesController < ApplicationController
|
||||||
|
|
||||||
|
def index
|
||||||
|
@languages = Language.all
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@language = Language.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@language = Language.new(language_params)
|
||||||
|
if @language.save
|
||||||
|
flash[:notice] = "Language successfully created."
|
||||||
|
redirect_to languages_path
|
||||||
|
else
|
||||||
|
render :new, status: :unprocessable_entity
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@language = Language.find_by_id(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
@language = Language.find_by_id(params[:id])
|
||||||
|
if @language.update(language_params)
|
||||||
|
flash[:notice] = "Language successfully updated."
|
||||||
|
redirect_to languages_path
|
||||||
|
else
|
||||||
|
render :edit, status: :unprocessable_entity
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@language = Language.find_by_id(params[:id])
|
||||||
|
if @language.destroy
|
||||||
|
flash[:notice] = "Language successfully deleted."
|
||||||
|
redirect_to languages_path
|
||||||
|
else
|
||||||
|
render :index, status: :not_modified
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def language_params
|
||||||
|
params.require(:language).permit(:name)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
2
app/helpers/language_helper.rb
Normal file
2
app/helpers/language_helper.rb
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
module LanguageHelper
|
||||||
|
end
|
@ -1,3 +1,4 @@
|
|||||||
class Definition < ApplicationRecord
|
class Definition < ApplicationRecord
|
||||||
belongs_to :word
|
belongs_to :word
|
||||||
|
belongs_to :language
|
||||||
end
|
end
|
||||||
|
6
app/models/language.rb
Normal file
6
app/models/language.rb
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
class Language < ApplicationRecord
|
||||||
|
has_many :definitions
|
||||||
|
has_many :part_of_speeches
|
||||||
|
|
||||||
|
validates_presence_of :name
|
||||||
|
end
|
@ -1,2 +1,3 @@
|
|||||||
class PartOfSpeech < ApplicationRecord
|
class PartOfSpeech < ApplicationRecord
|
||||||
|
belongs_to :language
|
||||||
end
|
end
|
||||||
|
5
app/views/languages/_errors.html.erb
Normal file
5
app/views/languages/_errors.html.erb
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<% if language.errors.any? %>
|
||||||
|
<% language.errors.full_messages.each do |message| %>
|
||||||
|
<h6><%= message %></h6>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
6
app/views/languages/_form.html.erb
Normal file
6
app/views/languages/_form.html.erb
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<%= form_for language do |f| %>
|
||||||
|
<%= f.label :name %>
|
||||||
|
<%= f.text_field :name %><br/>
|
||||||
|
<br/>
|
||||||
|
<%= f.submit %>
|
||||||
|
<% end %>
|
2
app/views/languages/create.html.erb
Normal file
2
app/views/languages/create.html.erb
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<h1>Language#create</h1>
|
||||||
|
<p>Find me in app/views/language/create.html.erb</p>
|
2
app/views/languages/destroy.html.erb
Normal file
2
app/views/languages/destroy.html.erb
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<h1>Language#destroy</h1>
|
||||||
|
<p>Find me in app/views/language/destroy.html.erb</p>
|
5
app/views/languages/edit.html.erb
Normal file
5
app/views/languages/edit.html.erb
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<%= render "languages/errors", language: @language %>
|
||||||
|
|
||||||
|
<h1>Edit Language</h1>
|
||||||
|
|
||||||
|
<%= render "languages/form", language: @language %>
|
20
app/views/languages/index.html.erb
Normal file
20
app/views/languages/index.html.erb
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<h1>Languages</h1>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td><b>Language</b></td>
|
||||||
|
</tr>
|
||||||
|
<% @languages.each do |language| %>
|
||||||
|
<tr>
|
||||||
|
<td><%= language.name %></td>
|
||||||
|
<td><%= link_to "Edit", edit_language_path(language) %></td>
|
||||||
|
<td> | </td>
|
||||||
|
<td><%= link_to "Delete", language_path(language), data: { turbo_method: :delete,
|
||||||
|
turbo_confirm: "Are you sure?" } %></td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
|
<%= link_to "New Language", new_language_path %>
|
5
app/views/languages/new.html.erb
Normal file
5
app/views/languages/new.html.erb
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<%= render "languages/errors", language: @language %>
|
||||||
|
|
||||||
|
<h1>New Language</h1>
|
||||||
|
|
||||||
|
<%= render "languages/form", language: @language %>
|
2
app/views/languages/show.html.erb
Normal file
2
app/views/languages/show.html.erb
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<h1>Language#show</h1>
|
||||||
|
<p>Find me in app/views/language/show.html.erb</p>
|
2
app/views/languages/update.html.erb
Normal file
2
app/views/languages/update.html.erb
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<h1>Language#update</h1>
|
||||||
|
<p>Find me in app/views/language/update.html.erb</p>
|
@ -15,6 +15,10 @@
|
|||||||
<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? %>
|
||||||
|
<pre style="display: inline;">|</pre>
|
||||||
|
<%= link_to "Languages", languages_path %>
|
||||||
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
<div class="ms-auto p-2">
|
<div class="ms-auto p-2">
|
||||||
<% if user_signed_in? %>
|
<% if user_signed_in? %>
|
||||||
|
@ -3,6 +3,7 @@ Rails.application.routes.draw do
|
|||||||
#get 'dictionary/index'
|
#get 'dictionary/index'
|
||||||
resources :dictionary, only: [:index, :show]
|
resources :dictionary, only: [:index, :show]
|
||||||
resources :words, only: [:index, :show]
|
resources :words, only: [:index, :show]
|
||||||
|
resources :languages
|
||||||
# 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.
|
||||||
|
9
db/migrate/20231025010204_create_languages.rb
Normal file
9
db/migrate/20231025010204_create_languages.rb
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
class CreateLanguages < ActiveRecord::Migration[7.1]
|
||||||
|
def change
|
||||||
|
create_table :languages do |t|
|
||||||
|
t.string :name
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
17
db/migrate/20231025010226_add_language_fields.rb
Normal file
17
db/migrate/20231025010226_add_language_fields.rb
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
class AddLanguageFields < ActiveRecord::Migration[7.1]
|
||||||
|
def change
|
||||||
|
create_table :language do |t|
|
||||||
|
t.string :name
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
|
||||||
|
change_table :definitions do |t|
|
||||||
|
t.references :language, null: false, foreign_key: true
|
||||||
|
end
|
||||||
|
|
||||||
|
change_table :part_of_speeches do |t|
|
||||||
|
t.references :language, null: false, foreign_key: true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
20
db/schema.rb
generated
20
db/schema.rb
generated
@ -10,21 +10,37 @@
|
|||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema[7.1].define(version: 2023_10_13_214519) do
|
ActiveRecord::Schema[7.1].define(version: 2023_10_25_010226) do
|
||||||
create_table "definitions", force: :cascade do |t|
|
create_table "definitions", force: :cascade do |t|
|
||||||
t.string "pos"
|
t.string "pos"
|
||||||
t.string "definition"
|
t.string "definition"
|
||||||
t.integer "word_id", null: false
|
t.integer "word_id", null: false
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
|
t.integer "language_id", null: false
|
||||||
|
t.index ["language_id"], name: "index_definitions_on_language_id"
|
||||||
t.index ["word_id"], name: "index_definitions_on_word_id"
|
t.index ["word_id"], name: "index_definitions_on_word_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table "language", force: :cascade do |t|
|
||||||
|
t.string "name"
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.datetime "updated_at", null: false
|
||||||
|
end
|
||||||
|
|
||||||
|
create_table "languages", force: :cascade do |t|
|
||||||
|
t.string "name"
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.datetime "updated_at", null: false
|
||||||
|
end
|
||||||
|
|
||||||
create_table "part_of_speeches", force: :cascade do |t|
|
create_table "part_of_speeches", force: :cascade do |t|
|
||||||
t.string "pos"
|
t.string "pos"
|
||||||
t.string "definition"
|
t.string "definition"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
|
t.integer "language_id", null: false
|
||||||
|
t.index ["language_id"], name: "index_part_of_speeches_on_language_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "users", force: :cascade do |t|
|
create_table "users", force: :cascade do |t|
|
||||||
@ -45,5 +61,7 @@ ActiveRecord::Schema[7.1].define(version: 2023_10_13_214519) do
|
|||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
add_foreign_key "definitions", "languages"
|
||||||
add_foreign_key "definitions", "words"
|
add_foreign_key "definitions", "words"
|
||||||
|
add_foreign_key "part_of_speeches", "languages"
|
||||||
end
|
end
|
||||||
|
@ -1,14 +1,24 @@
|
|||||||
namespace :dataset do
|
namespace :dataset do
|
||||||
desc "TODO"
|
desc "TODO"
|
||||||
task ingest: :environment do
|
task ingest: :environment do
|
||||||
ingest_pos
|
english = create_english_lang
|
||||||
ingest_dictionary
|
ingest_pos(english)
|
||||||
|
ingest_dictionary(english)
|
||||||
puts "Ingest complete."
|
puts "Ingest complete."
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def ingest_pos
|
def create_english_lang
|
||||||
|
if Language.count > 0
|
||||||
|
puts "Language English already exists! Skipping step."
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
return Language.create(name: "English")
|
||||||
|
end
|
||||||
|
|
||||||
|
def ingest_pos(language)
|
||||||
if PartOfSpeech.count > 0
|
if PartOfSpeech.count > 0
|
||||||
puts "Parts of speech data already exists in table! Aborting."
|
puts "Parts of speech data already exists in table! Aborting."
|
||||||
return
|
return
|
||||||
@ -17,12 +27,12 @@ def ingest_pos
|
|||||||
parts_of_speech = JSON.parse(File.read('db/dataset_en/toki-partsofspeech.json'))
|
parts_of_speech = JSON.parse(File.read('db/dataset_en/toki-partsofspeech.json'))
|
||||||
|
|
||||||
parts_of_speech.each do |pos|
|
parts_of_speech.each do |pos|
|
||||||
PartOfSpeech.create(pos: pos['pos'], definition: pos['definition'])
|
PartOfSpeech.create(pos: pos['pos'], definition: pos['definition'], language_id: language.id)
|
||||||
end
|
end
|
||||||
puts "Parts of speech ingest complete."
|
puts "Parts of speech ingest complete."
|
||||||
end
|
end
|
||||||
|
|
||||||
def ingest_dictionary
|
def ingest_dictionary(language)
|
||||||
if Word.count > 0
|
if Word.count > 0
|
||||||
puts "Dictionary data already exists in table! Aborting."
|
puts "Dictionary data already exists in table! Aborting."
|
||||||
return
|
return
|
||||||
@ -37,7 +47,7 @@ def ingest_dictionary
|
|||||||
word = Word.create(word: entry['word'])
|
word = Word.create(word: entry['word'])
|
||||||
|
|
||||||
entry['definitions'].each do |definition|
|
entry['definitions'].each do |definition|
|
||||||
word.definitions.create(pos: definition['pos'], definition: definition['definition'])
|
word.definitions.create(pos: definition['pos'], definition: definition['definition'], language_id: language.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
puts "Dictionary ingest complete."
|
puts "Dictionary ingest complete."
|
||||||
|
@ -2,6 +2,7 @@ FactoryBot.define do
|
|||||||
factory :definition do
|
factory :definition do
|
||||||
pos { "n" }
|
pos { "n" }
|
||||||
definition { "this is a definition" }
|
definition { "this is a definition" }
|
||||||
|
language_id { FactoryBot.create(:language).id }
|
||||||
word_id { FactoryBot.create(:word).id }
|
word_id { FactoryBot.create(:word).id }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
5
spec/factories/languages.rb
Normal file
5
spec/factories/languages.rb
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
FactoryBot.define do
|
||||||
|
factory :language do
|
||||||
|
name { "MyString" }
|
||||||
|
end
|
||||||
|
end
|
@ -1,6 +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 }
|
||||||
definition { "test definition" }
|
definition { "test definition" }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
4
spec/models/language_spec.rb
Normal file
4
spec/models/language_spec.rb
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe Language, type: :model do
|
||||||
|
end
|
106
spec/requests/language_spec.rb
Normal file
106
spec/requests/language_spec.rb
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe "Languages", type: :request do
|
||||||
|
|
||||||
|
describe "GET :index" do
|
||||||
|
it "returns http success" do
|
||||||
|
get "/languages/"
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "lists all languages" do
|
||||||
|
language = FactoryBot.create(:language)
|
||||||
|
get "/languages/"
|
||||||
|
expect(response.body).to include(language.name)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "has a new-language link" do
|
||||||
|
get "/languages/"
|
||||||
|
expect(response.body).to have_selector(%(a[href="#{new_language_path}"]))
|
||||||
|
end
|
||||||
|
|
||||||
|
it "has an edit button" do
|
||||||
|
language = FactoryBot.create(:language)
|
||||||
|
get "/languages/"
|
||||||
|
expect(response.body).to have_link("Edit")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "has a delete button" do
|
||||||
|
language = FactoryBot.create(:language)
|
||||||
|
get "/languages/"
|
||||||
|
expect(response.body).to have_link("Delete")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "GET :new" do
|
||||||
|
it "returns http success" do
|
||||||
|
get "/languages/new"
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "has a form for a new language" do
|
||||||
|
get "/languages/new"
|
||||||
|
expect(response.body).to have_selector(%(input[name="language[name]"]))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "POST :create" do
|
||||||
|
it "redirect to languages_path on success" do
|
||||||
|
post "/languages", params: { language: { name: "Test Name" } }
|
||||||
|
expect(response).to redirect_to(languages_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "creates a new language" do
|
||||||
|
post "/languages", params: { language: { name: "Test Name" } }
|
||||||
|
expect(Language.count).to eq(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "requires a name for a new language" do
|
||||||
|
post "/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 "/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 "/languages/#{@language.id}", params: @params
|
||||||
|
expect(response).to redirect_to(languages_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "requires params to update a language" do
|
||||||
|
@params = { language: { name: nil, invalid: "oh no" } }
|
||||||
|
patch "/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 "/languages/#{language.id}"
|
||||||
|
expect(Language.all).to eq([language2])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -27,6 +27,12 @@ RSpec.describe "Root path", type: :request do
|
|||||||
expect(response.body).to include("Sign Out")
|
expect(response.body).to include("Sign Out")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "should have the 'Languages' link" do
|
||||||
|
sign_in FactoryBot.create(:user)
|
||||||
|
get root_path
|
||||||
|
expect(response.body).to have_selector(%(a[href="#{languages_path}"]))
|
||||||
|
end
|
||||||
|
|
||||||
it "should welcome user by username" do
|
it "should welcome user by username" do
|
||||||
user = FactoryBot.create(:user)
|
user = FactoryBot.create(:user)
|
||||||
sign_in user
|
sign_in user
|
||||||
|
@ -1,11 +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
|
|
||||||
end
|
|
0
spec/views/.keep
Normal file
0
spec/views/.keep
Normal file
Loading…
Reference in New Issue
Block a user