WordMine is a web application inspired by Duolingo. It uses a Postgres database and a React frontend, implementing Redux for controlling data flow.
Users' information is kept extremely secure. WordMine uses BCrypt to hash users' passwords and create password_digests. It uses SecureRandom.urlsafe_base64(32) to create session tokens. Passwords themselves are never stored anywhere and session tokens only live in the database and are kept off the front end. When requests are made to the database, WordMine implements strong parameters to prevent users from being able to make requests with malicious data.The seeds file creates data dynamically, which makes it easy to add content to the site. When the seeds file runs, it creates trees based on the names of the folders in `'lib/assets'`:
Dir.entries('./lib/assets').reject{|f| f =~ /^\./}.each do |tree_name|
Tree.create!({name: tree_name})
end
Then it creates WordList
s based on the filenames within those folders, and creates Word
s based on the content of those files:
Each model validates its most important info. There are also database-level validations. The TreesUser
model represents connections between users and the languages they study. The WordList
model exists in order to avoid creating duplicate words. This works because users have their own nodes, which are created when the user chooses a language. Without a WordList
model, new words would have to be created every time a node is created so that associations could be set up properly. With the WordList
model, new nodes simply store a word_list_id, which points to the appropriate WordList
, which has_many
Word
s.
The controllers are:
- UsersController
- SessionsController
- TreesController
- NodesController
- TreesUsersController
All controllers live in an API folder and JSON is set as the default format for all responses. Requests to the controllers are triggered by React components and sent in the form of $.ajax requests. Responses are formatted using JBuilder.
A WordsController was not necessary because requests to the NodesController
's show method sends back a node which contains an array of the words that belong to its WordList
:
json.array! @node.word_list.words.shuffle
The TreesUsersController's purpose is to receive POST
requests from the ChooseLanguage component. It creates the user's nodes, creates a new TreesUser
object, and renders its show method, which returns the appropriate tree and node data to display on the Tree
page.