Add Language model and LanguageController

This commit is contained in:
maddiebaka 2023-10-24 23:47:01 -04:00
parent ed00e69a13
commit 206c4da31f
28 changed files with 298 additions and 18 deletions

View 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

View File

@ -0,0 +1,2 @@
module LanguageHelper
end

View File

@ -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
View File

@ -0,0 +1,6 @@
class Language < ApplicationRecord
has_many :definitions
has_many :part_of_speeches
validates_presence_of :name
end

View File

@ -1,2 +1,3 @@
class PartOfSpeech < ApplicationRecord class PartOfSpeech < ApplicationRecord
belongs_to :language
end end

View File

@ -0,0 +1,5 @@
<% if language.errors.any? %>
<% language.errors.full_messages.each do |message| %>
<h6><%= message %></h6>
<% end %>
<% end %>

View File

@ -0,0 +1,6 @@
<%= form_for language do |f| %>
<%= f.label :name %>
<%= f.text_field :name %><br/>
<br/>
<%= f.submit %>
<% end %>

View File

@ -0,0 +1,2 @@
<h1>Language#create</h1>
<p>Find me in app/views/language/create.html.erb</p>

View File

@ -0,0 +1,2 @@
<h1>Language#destroy</h1>
<p>Find me in app/views/language/destroy.html.erb</p>

View File

@ -0,0 +1,5 @@
<%= render "languages/errors", language: @language %>
<h1>Edit Language</h1>
<%= render "languages/form", language: @language %>

View 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 %>

View File

@ -0,0 +1,5 @@
<%= render "languages/errors", language: @language %>
<h1>New Language</h1>
<%= render "languages/form", language: @language %>

View File

@ -0,0 +1,2 @@
<h1>Language#show</h1>
<p>Find me in app/views/language/show.html.erb</p>

View File

@ -0,0 +1,2 @@
<h1>Language#update</h1>
<p>Find me in app/views/language/update.html.erb</p>

View File

@ -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? %>

View File

@ -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.

View 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

View 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
View File

@ -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

View File

@ -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."

View File

@ -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

View File

@ -0,0 +1,5 @@
FactoryBot.define do
factory :language do
name { "MyString" }
end
end

View File

@ -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

View File

@ -0,0 +1,4 @@
require 'rails_helper'
RSpec.describe Language, type: :model do
end

View 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

View File

@ -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

View File

@ -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
View File