cd work_dir # where work_dir is a directory of your choice
mkdir rails # create rails directory
cd rails
rails new mydiary # This rails command will create a mydiary project directory.
cd mydiary
* All the newly-created directories in the ''mydiary'' directory will make up the //mydiary// rails web app.
* app: Contains most of the Ruby source code and output templates directly associated with the app; most directly connected to the MVC components of the Web app.
* app/controllers: Contains the controller files
* app/helpers: Contains ruby source code files that provide methods that you can use from views
* app/views: Contains output templates (views) for the app.
* config: Contains configuration files for the app.
* db: Used for database dumps, backups and migrations. In the case of apps that use SQLite, may contains the database file(s).
* storage: (Newer versions of Rails) Contains database files from migration operations.
* bin: Contains important scripts and command line tools used in constructing and deploying Rails apps.
* The ''Gemfile'' in ''mydiary'' belongs to ''[[http://bundler.io|bundler]]'', which manages Ruby gems dependencies for your new rails project.
* ''Gemfile'' can be customized in a text editor if needed to add custom gem dependencies to your project.
==== Database (SQLite3) Config ====
* See config/database.yml
* ''database.yml'' is a [[http://en.wikipedia.org/wiki/YAML | YAML]] file with info about the database(s) that the app will use.
* Note "development," "test" and "production" targets.
==== Using "Scaffolding" ====
* The Rails scaffolding mechanism generates default, generic code to provide a full set of basic Web app operations for any of your models.
* These "Web app operations" are the //CRUD (Create, Retrieve, Update, and Delete)// operations and views on any database table
* You can then build your own views and controller methods off of this basic scaffolding.
* Run the following command in the Terminal:
rails generate scaffold Entry title:string content:text
* For our //mydiary// application, entries will initially solely consist of a title and some content.
* There are other attributes (or "fields" in the database sense) that Rails will add by default to the underlying database table, such as //id// (a unique numeric identifier).
* A directive is also added into the default migration (database creation) code to create timestamp columns: //created_at// (a timestamp of when the record/associated object was created), and //updated_at// (a timestamp of when the record/associated object was amended last).
* Because of this automation, it is only necessary to specify the two custom, additional attributes to the scaffold generator to get things going.
==== Migrations to create db tables ====
* We're building an online diary.
* **Our model is the diary entry that we'll call //Entry//.**
* The scaffolding step above defined our database table and its fields to reflect the structure of our model.
* **In Rails, models and database tables generally have a direct relationship.**
* If you have a database table called //entries//, then this will be directly related to a model class in your Rails app called //Entry//.
* Rails naming conventions
* expects objects from a singular class name to be saved to a database table which is the plural of the class name
* Example: expects objects from the class Person to be saved to a database table named people (not "persons")
* Rails has a //pluralization engine// to figure out what object maps to what table.
* Database tables can be created directly with SQL or other db frontend if desired.
* But the preferred way is to use //migrations//.
* Migrations are mostly database-independent and allow you to manage changes to your db's schema over time and give you the ability to "roll back" to older versions of your schema.
* See the migration script that was automatically generated by the previous ''generate scaffold'' command. It will be a .rb script found in ''db/migrate'' that looks something like this:
# .rb script in the db/migrate directory of the rails project
#
class CreateEntries < ActiveRecord::Migration[8.0]
def change
create_table :entries do |t|
t.string :title
t.text :content
t.timestamps
end
end
end
* By default, table names are pluralized and model names are singular.
* Example: table name //entries// & model name //Entry//
* Rails works out the difference between singular and plural names automatically.
* Use the Rails ''rake'' command to create the database tables using a migration.
* ''rake'' tasks are administrative tasks associated with your app that are managed by the ''rake'' tool.
* This tool is analogous to the ''make'' command used for C/C++ development.
* Notice the ''Rakefile'' in the root of your app directory structure.
* After running the following ''rake'' command, you should notice a SQLite database file ''development.sqlite3'' in the ''db'' project directory.
* Note: In newer versions of rails, ''development.sqlite3'' will be found in the ''storage'' project directory.
### Recommended in rails 4+ (bundle forces use of the rake version specified in Gemfile) ###
bundle exec rake db:migrate
### If you don't have the 'bundle' command after installing rails (Windows), then just run
###
### rake db:migrate
==== Configure web app access host authorization (SP23, Rails 6+) ====
* Per https://www.fngtps.com/2019/rails6-blocked-host
* Edit the ''config/environments/development.rb'' file and add the following code somewhere inside the ''Rails.application.configure do'' block:
# Authorize access from any host:
config.hosts.clear
==== Start simple web server and view current web app ====
rails server -b 0.0.0.0 -p
### = some value >= 3000 ###
* Running the above ''rails server...'' command should start a simple development web server to serve your app.
* Start a web browser on the same host that the rails server is running on, and browse the URL and port that the web server provides.
* For example, if simple web server output includes "0.0.0.0:3010", browse the rails app using the URL
<%### _entry.html.erb (partial) ###%>
Title:
<%= entry.title %>
Content:
<%= entry.content %>
<%### show.html.erb ###%>
<%= notice %>
<%### Use _entry.html.erb partial ###%>
<%= render @entry %>
<%= link_to "Edit this entry", edit_entry_path(@entry) %> |
<%= link_to "Back to entries", entries_path %>
<%= button_to "Destroy this entry", @entry, method: :delete %>
* ERB files may contain different forms of the <% tag. The differences between them are explained at https://stackoverflow.com/questions/7996695/what-is-the-difference-between-and-in-erb-in-rails
==== Creating a New Action and View ====
* Try adding a new method manually to the Entries controller (in ''app/controllers/entries_controller.rb''):
# Defines a new method and, therefore, a new controller action.
# Similar to index, but sorted in descending (DESC) order
# by creation time.
# GET /entries/view_all
def view_all
@entries = Entry.order('created_at DESC').all
end
* If we want to use this new controller method, it is necessary to tell the Rails routing system (the system that sends incoming request to the correct controllers and methods) that you have defined a new method that may be called on the entries controller.
* We need to edit the ''config/routes.rb'' file, and add some statements just **BEFORE** the following line (2nd line of file):
resources :entries
* The statements to add are:
# Redefining root route as the view_all action:
root 'entries#view_all'
# Defining this route to use new view_all controller action:
get '/entries/view_all' => 'entries#view_all'
* After that, attempting to use the new //view_all// method at
<%# view_all.html.erb: Define the view for the view_all controller action. %>
<%= link_to 'Add New entry', controller: 'entries', action: 'new' %>
<% @entries.each do |entry| %>
<%= entry.title %>
<%= entry.content %>
Posted at <%= entry.created_at %>
<%= link_to "Show this entry", entry %>
<% end %>
* See the current mydiary app routes by running the following command in a Terminal:
rails routes
* Retry the view_all controller method by visiting
<%# index.html.erb: Tabular index view with all actions %>
Listing Entries
Title
Content
<% @entries.each do |entry| %>
<%= entry.title %>
<%= entry.content %>
<%= link_to 'Show', entry %>
<%= link_to 'Edit', edit_entry_path(entry) %>
<%= button_to 'Delete', entry, method: :delete, data: { turbo_confirm: 'Are you sure?' } %>
<% end %>
<%= link_to 'New Entry', new_entry_path %>
----