Cet article approfondit ma compréhension en écrivant un article de commentaire du tutoriel Rails pour solidifier davantage mes connaissances Cela fait partie de mon étude. Dans de rares cas, il peut contenir un contenu ridicule ou incorrect. Notez s'il vous plaît. J'apprécierais que vous me disiez implicitement ...
La source Tutoriel Rails 6e édition
Apprenez les fonctionnalités puissantes de l'échafaudage grâce à la création de toy_app Obtenez une idée approximative de ce qu'est l'architecture REST.
① Spécifiez la version de Rails et générez-la de la même manière que hello_app
$ cd ~/environment
$ rails _6.0.3_ new toy_app
$ cd toy_app/
② Gemfile est également nouveau, alors réécrivez-le pour l'application Toy
Gemfile
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
gem 'rails', '6.0.3'
gem 'puma', '4.3.4'
gem 'sass-rails', '5.1.0'
gem 'webpacker', '4.0.7'
gem 'turbolinks', '5.2.0'
gem 'jbuilder', '2.9.1'
gem 'bootsnap', '1.4.5', require: false
group :development, :test do
gem 'sqlite3', '1.4.1'
gem 'byebug', '11.0.1', platforms: [:mri, :mingw, :x64_mingw]
end
group :development do
gem 'web-console', '4.0.1'
gem 'listen', '3.1.5'
gem 'spring', '2.1.0'
gem 'spring-watcher-listen', '2.0.1'
end
group :test do
gem 'capybara', '3.28.0'
gem 'selenium-webdriver', '3.142.4'
gem 'webdrivers', '4.1.2'
end
group :production do
gem 'pg', '1.1.4'
end
#Tzinfo pour les informations de fuseau horaire sous Windows-doit inclure un gemme de données
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
③ Et comme avant
bundle install
Courir,
You have requested:
listen = 3.1.5
The bundle currently has listen locked at 3.2.1.
Try running `bundle update listen`
If you are updating multiple gems in your Gemfile at once,
try passing them all to `bundle update`
Si vous obtenez une erreur comme celle-ci, elle est bloquée dans Gemfile.lock, supprimez donc Gemfile.lock une fois.
bundle update
Après avoir couru
bundle install
Faire.
④ Enfin, placez-le sous le contrôle de version Git comme hello_app.
$ git init
$ git add -A
$ git commit -m "Initialize repository"
Maintenant que vous disposez d'un référentiel local, créez un nouveau référentiel distant pour votre application Toy. Pousser. (Créez un référentiel distant sur le site Github de la même manière qu'au chapitre 1) Le référentiel est toujours privé.
$ git remote add origin https://github.com/<Le nom de votre compte GitHub>/toy_app.git
$ git push -u origin master
⑤ Essayez de déployer pour le moment. Dans l'état actuel, il n'y a pas de contenu, donc pour le moment, tout comme hello_app Ajouter à la sortie bonjour, monde
application_controller.rb
class ApplicationController < ActionController::Base
def hello
render html: "hello, world!"
end
end
routes.rb
Rails.application.routes.draw do
root 'application#hello'
end
Puis validez ce changement et envoyez-le à Github / Heroku
$ git commit -am "Add hello"
$ heroku create
$ git push && git push heroku master
From Rails Tutorial 6e édition https://railstutorial.jp/chapters/toy_app?version=6.0#sec-modeling_demo_users
Les attributs id, name et email correspondent aux colonnes de la table.
Les micro-messages sont censés être de courts messages d'environ 140 caractères, similaires aux tweets Twitter. Si vous ajoutez l'id de l'article, le contenu du type de texte qui stocke le contenu textuel de l'article et l'ID utilisateur pour enregistrer qui l'a publié
From Rails Tutorial 6e édition https://railstutorial.jp/chapters/toy_app?version=6.0#sec-modeling_demo_microposts
Cela devient un tel modèle de données.
Générez des rails à partir de la ressource Users avec le générateur d'échafaudage.
$ rails generate scaffold User name:string email:string
Il est écrit lorsque les rails génèrent le nom de la colonne du nom de la ressource d'échafaudage: type de données ~. L'attribut id est toujours ajouté en tant que clé primaire à un modèle, il n'est donc pas nécessaire de l'écrire.
J'ai créé un modèle utilisateur avec échafaudage, mais je ne peux pas l'utiliser tel quel. La base de données créée par le générateur doit être migrée.
Migrer la base de données ↓
$ rails db:migrate
Maintenant que vous pouvez exécuter votre serveur Web local, si vous utilisez Cloud9 Modifiez development.rb comme dans le chapitre 1 pour autoriser la connexion à Cloud9.
development.rb
Rails.application.configure do
.
.
.
config.hosts.clear
end
Après cela, démarrez le terminal dans un autre onglet et exécutez
rails server```.
Cela lancera le serveur local et affichera bonjour, monde!.
En générant la ressource Utilisateurs avec échafaudage dans la série d'étapes ci-dessus, de nombreuses pages de gestion des utilisateurs sont automatiquement ajoutées. L'URL et le contenu de la page sont les suivants.
URL | action | Utilisation |
---|---|---|
/users | index | Page répertoriant tous les utilisateurs |
/users/1 | show | id=Page pour afficher 1 utilisateur |
/users/new | new | Page pour créer un nouvel utilisateur |
/users/1/edit | edit | id=Page pour éditer 1 utilisateur |
From Rails Tutorial 6e édition https://railstutorial.jp/chapters/toy_app?version=6.0#sec-a_user_tour
Consultez le didacticiel Rails pour explorer la page utilisateur.
Lorsque vous ouvrez la page d'index de / users, le type de traitement effectué en interne est illustré dans MVC comme ceci. From Rails Tutorial 6e édition https://railstutorial.jp/chapters/toy_app?version=6.0#sec-mvc_in_action
Requête du navigateur → Attribuée à l'action correspondante par le routeur → Interroger le modèle utilisateur pour les données requises → Le modèle récupère les données de la base de données → Le modèle transmet les données au contrôleur → Affectez les données reçues à la variable d'instance et transmettez-les à la vue → La vue génère du HTML et le transmet au contrôleur → Renvoie le HTML reçu par le contrôleur au navigateur Le flux.
Maintenant que l'application Toy a été créée pour le moment, essayez de remplacer l'URL racine par la page d'index de l'application Toy.
routes.rb
Rails.application.routes.draw do
resources :users
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
root "users#index"
end
La méthode d'écriture est la même cette fois également, et elle est décrite par "nom du contrôleur # nom de l'action"
Jetons un coup d'œil au users_controller généré par scaffold.
users_controller.rb
class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]
# GET /users
# GET /users.json
def index
@users = User.all
end
# GET /users/1
# GET /users/1.json
def show
end
# GET /users/new
def new
@user = User.new
end
# GET /users/1/edit
def edit
end
Une telle description est faite. La description de UsersController <ApplicationController sur la première ligne Signifie l'héritage dans la syntaxe Ruby. ici Cela signifie la classe UserController qui hérite de ApplicationController.
Le tableau ci-dessous répertorie les actions qui prennent en charge REST. Certaines URL sont dupliquées, mais elles sont comptées comme des routes différentes car le type de requête HTTP est différent.
Requête HTTP | URL | action | Utilisation |
---|---|---|---|
GET | /users | index | Page répertoriant tous les utilisateurs |
GET | /users/1 | show | id=Page pour afficher 1 utilisateur |
GET | /users/new | new | Page pour créer un nouvel utilisateur |
POST | /users | create | Action pour créer un utilisateur |
GET | /users/1/edit | edit | id=Page pour éditer 1 utilisateur |
PATCH | /users/1 | update | id=Action pour mettre à jour 1 utilisateur |
DELETE | /users/1 | destroy | id=Action pour supprimer 1 utilisateur |
From Rails Tutorial 6e édition https://railstutorial.jp/chapters/toy_app?version=6.0#table-demo_RESTful_users
Examen de l'action d'index de users_controller
def index
@users = User.all
end
C'est écrit comme ça. Il s'agit d'un traitement pour récupérer et affecter toutes les données de la base de données User à la variable @users.
Le modèle utilisateur lui-même est très simple sans description Parce que la "classe ActiveRecord" héritée par la classe User a autant de fonctions liées aux opérations DB. Dans ce cas, User.all a pu récupérer les données utilisateur de la base de données.
Cette variable @users est utilisée dans la vue d'index qui correspond à l'action d'index. Regardons le lieu pertinent.
erb:index.html.erb
<% @users.each do |user| %>
<tr>
<td><%= user.name %></td>
<td><%= user.email %></td>
<td><%= link_to 'Show', user %></td>
<td><%= link_to 'Edit', edit_user_path(user) %></td>
<td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
De cette description<% @users.each do |user| %>
Mais la partie
Pour expliquer brièvement à ce stade, extrayez les données (enregistrements) contenues dans la variable @users une par une.
Processus d'attribution à l'utilisateur et de répétition de la partie entourée de fin pour le nombre d'enregistrements.
S'il y a 3 utilisateurs (A, B, C)
Mettez les données de A dans l'utilisateur et générez du HTML
Mettez les données B dans l'utilisateur et générez du HTML
Mettre les données C dans l'utilisateur et générer du HTML
Un traitement itératif est effectué.
Vous n'avez pas à comprendre à ce stade
① Une requête est envoyée du navigateur au routeur (2) Le routeur l'affecte à l'action d'édition du contrôleur correspondant à la requête. ③ Demandez les données requises par l'action d'édition à partir du modèle. ④ Le modèle lit les données demandées dans la base de données et les renvoie au contrôleur. ⑤ Appelez la vue edit.html.erb correspondant à l'action d'édition (à ce moment, passez les données lues à la vue) ⑥ La vue génère du HTML et le renvoie au contrôleur. ⑦ Le contrôleur renvoie le code HTML transmis au navigateur.
Il est décrit dans la méthode privée de users_controller.
users_controller.rb
class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]
private
# Use callbacks to share common setup or constraints between actions.
def set_user
@user = User.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def user_params
params.require(:user).permit(:name, :email)
end
end
La description before_action spécifie que la méthode set_user doit être exécutée avant d'exécuter l'action d'édition. Dans l'action ser_user, la variable @user contient une instruction permettant de lire la table des ID demandés dans la base de données User.
3.edit.html.erb
Comme je l'ai mentionné dans l'exercice précédent, je peux m'inscrire même si mon nom d'utilisateur et mon adresse e-mail sont erronés.
De plus, comme il n'y a pas de mécanisme de connexion, n'importe qui peut supprimer ou modifier l'utilisateur. Il n'y a pas d'autorité ou de merde.
Et il n'y a presque aucun test pour confirmer le fonctionnement de l'application. Le contenu ci-dessus est-il correct? Si les fonctions de l'application fonctionnent correctement, etc. Pas du tout testé. → Je ne le trouve pas même s'il y a quelque chose qui ne va pas
L'interface utilisateur est moche et la mise en page est foirée Personne n'utilise une application Web avec une telle mise en page (affirmation)
Difficile à comprendre. Épuisé à ça Il est difficile de comprendre pleinement le code, même pour moi-même, qui a lu le didacticiel Rails pendant une semaine. Le code est essentiellement concis et facile à comprendre
Générons des Microposts avec échafaudage ainsi que des utilisateurs.
$ rails g scaffold Micropost content:text user_id:integer
Running via Spring preloader in process 3794
invoke active_record
create db/migrate/20200601141608_create_microposts.rb
create app/models/micropost.rb
invoke test_unit
create test/models/micropost_test.rb
create test/fixtures/microposts.yml
invoke resource_route
route resources :microposts
invoke scaffold_controller
create app/controllers/microposts_controller.rb
invoke erb
create app/views/microposts
create app/views/microposts/index.html.erb
create app/views/microposts/edit.html.erb
create app/views/microposts/show.html.erb
create app/views/microposts/new.html.erb
create app/views/microposts/_form.html.erb
invoke test_unit
create test/controllers/microposts_controller_test.rb
create test/system/microposts_test.rb
invoke helper
create app/helpers/microposts_helper.rb
invoke test_unit
invoke jbuilder
create app/views/microposts/index.json.jbuilder
create app/views/microposts/show.json.jbuilder
create app/views/microposts/_micropost.json.jbuilder
invoke assets
invoke scss
create app/assets/stylesheets/microposts.scss
invoke scss
identical app/assets/stylesheets/scaffolds.scss
Commencez par migrer la base de données afin qu'elle puisse être utilisée de la même manière que lors de la création d'utilisateurs.
$ rails db:migrate
== 20200601141608 CreateMicroposts: migrating =================================
-- create_table(:microposts)
-> 0.0041s
== 20200601141608 CreateMicroposts: migrated (0.0048s) ========================
Microposts est identique à celui des utilisateurs, le routeur a été mis à jour et les ressources prennent désormais en charge l'architecture REST. Chaque routage est attribué.
Requête HTTP | URL | action | Utilisation |
---|---|---|---|
GET | /microposts | index | Page montrant tous les micro-messages |
GET | /microposts/1 | show | id=Page affichant 1 micropost |
GET | /microposts/new | new | Page pour créer un nouveau micro-message |
POST | /microposts | create | Action pour créer un nouveau micropost |
GET | /microposts/1/edit | edit | id=Page pour éditer 1 micro-message |
PATCH | /microposts/1 | update | id=Action pour mettre à jour 1 micropost |
DELETE | /microposts/1 | destroy | Supprimer le micropost avec id1 |
From Rails Tutorial 6e édition https://railstutorial.jp/chapters/toy_app?version=6.0#code-demo_microposts_resource
Le code généré par scaffold ne change pas sauf que le nom de la classe remplace le nom que vous lui avez donné. Autrement dit, il a la même structure.
Comme les utilisateurs, Microposts peut accéder à la page d'index avec / microposts et publier avec New micropost.
Comme il n'y a pas de limite de caractères dans le troisième élément de l'exercice précédent, même de longues phrases peuvent être affichées et un problème non micro a été découvert. Nous allons résoudre ce problème.
Résolvez ce problème en ajoutant des restrictions (validation) au contenu de la base de données. Le code spécifique est ci-dessous
micropost.rb
class Micropost < ApplicationRecord
validates :content, length:{maximum: 140}
end
Limitez le contenu à 140 caractères en écrivant la validation dans un modèle qui gère les bases de données. Ce code est Code très simple qui limite la longueur maximale du contenu à 140. Le nombre maximum de caractères dans un message peut être reformulé en 140 caractères.
Rails génère maintenant une erreur avec l'ajout de la validation. Voici l'écran où j'ai posté Micropost avec 140 caractères ou plus.
Super excellent.
Comme sur Twitter et Qiita "Un utilisateur a plusieurs messages" En d'autres termes Il peut y avoir plusieurs publications avec l'ID utilisateur 1. Rails facilite la mise en œuvre de ces relations de données un-à-plusieurs. Voici le code
user.rb
class User < ApplicationRecord
has_many :microposts
end
micropost.rb
class Micropost < ApplicationRecord
belongs_to :user
validates :content, length:{maximum: 140}
end
L'utilisateur dispose de plusieurs micro-messages. les micro-messages appartiennent à un seul utilisateur. Cette relation est implémentée dans ce code.
En écrivant ce code, vous pouvez afficher l'utilisateur à partir de la valeur de la colonne user_id de Microposts. Essayons-le réellement.
Tout d'abord, démarrez la console `` console rails '' qui peut utiliser les fonctions Rails. C'est très pratique car vous pouvez essayer librement les données et le code de la base de données dans la console rails. Tout d'abord, créez un utilisateur dans la console rails, puis créez un Micropost avec l'ID de cet utilisateur.
user1 = User.first
(0.4ms) SELECT sqlite_version(*)
User Load (0.1ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]]
=> #<User id: 1, name: "takemo", email: "[email protected]", created_at: "2020-05-31 14:00:23", updated_at: "2020-05-31 14:00:23">
2.6.3 :002 > user1.microposts
Remplacez les premières données enregistrées dans la base de données utilisateur par user1 Depuis que j'ai créé un utilisateur sur un serveur local à titre d'essai auparavant, ces données sont attribuées.
Voici une scène où l'association précédente est utile
> user1.microposts
Micropost Load (0.1ms) SELECT "microposts".* FROM "microposts" WHERE "microposts"."user_id" = ? LIMIT ? [["user_id", 1], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Micropost id: 1, content: "taskemodsjfa jl", user_id: 1, created_at: "2020-06-01 14:24:23", updated_at: "2020-06-01 14:24:23">, #<Micropost id: 3, content: "Ruby est Yukihiro Matsumoto (communément appelé):Script orienté objet développé par Matz)...", user_id: 1, created_at: "2020-06-01 14:27:03", updated_at: "2020-06-01 14:27:03">, #<Micropost id: 5, content: "L'association de différents modèles de données est une fonctionnalité puissante de Rails. Ici, plusieurs pour un utilisateur...", user_id: 1, created_at: "2020-06-01 14:41:51", updated_at: "2020-06-01 14:41:51">]>
2.6.3 :003 >
Étant donné que l'association a conduit à plusieurs Microposts associés à User, si vous utilisez user1. Vous pouvez récupérer tous les Microposts associés à user1. (Vous pouvez découvrir ce que l'utilisateur a publié.)
Essayez de l'utiliser dans la direction opposée (découvrez qui s'est rendu à la poste)
> micropost = user1.microposts.first
Micropost Load (0.1ms) SELECT "microposts".* FROM "microposts" WHERE "microposts"."user_id" = ? ORDER BY "microposts"."id" ASC LIMIT ? [["user_id", 1], ["LIMIT", 1]]
=> #<Micropost id: 1, content: "taskemodsjfa jl", user_id: 1, created_at: "2020-06-01 14:24:23", updated_at: "2020-06-01 14:24:23">
Le premier micropost de user1 (user_id = 1) a été affecté à la variable micropost. En d'autres termes, il suffit d'extraire l'utilisateur avec user_id 1 du micropost.
> micropost.user
=> #<User id: 1, name: "takemo", email: "[email protected]", created_at: "2020-05-31 14:00:23", updated_at: "2020-05-31 14:00:23">
2.6.3 :004 >
micropost.J'ai pu récupérer l'utilisateur auquel appartient le micropost simplement en le définissant comme utilisateur.
Cette utilisation pratique peut être obtenue simplement en implémentant une relation un-à-plusieurs à l'aide de has_many et appartient_to.
### Exercice
1. Vous pouvez afficher le contenu du premier micropost dans les micropostes de @user, donc si vous copiez et collez à partir d'une autre ligne telle quelle, ce sera comme ça.
#### **`erb:show.html.erb`**
<%= notice %>
Name: <%= @user.name %>
Email: <%= @user.email %>
Micropost_first <%= @user.microposts.first.content %>
<%= link_to 'Edit', edit_user_path(@user) %> | <%= link_to 'Back', users_path %>
↓ Résultat
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617753/8c6aa29f-73aa-5415-4030-0b0c5f4bd2d8.png)
2. Après avoir ajouté le code, lorsque je le publie en blanc
Je me suis fait prendre en validation et j'ai jeté une erreur.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617753/e9cff370-73a2-b6e8-16fb-b0b92c94d0db.png)
3. Pour FILL_IN, spécifiez la colonne à laquelle vous souhaitez appliquer la validation. (nom et email)
#### **`user.rb`**
```ruby
class User < ApplicationRecord
has_many :microposts
validates :name, presence: true
validates :email, presence: true
end
Depuis que j'ai ajouté la validation, j'ai commencé à lancer une erreur lorsque je me suis inscrit vide.
Même si vous comprenez quelque chose ici, c'est OK pour le moment
Le modèle Rails est hérité de la syntaxe spécifique à Ruby User <ApplicationRecord
.
La structure de l'héritage du modèle est celle illustrée dans la figure.
From Rails Tutorial 6e édition https://railstutorial.jp/chapters/toy_app?version=6.0#fig-demo_model_inheritance
Tous les modèles Rails tels que User et Micropost héritent de la classe ApplicationRecord. Et ApplicationRecord hérite d'une classe de base appelée ActiveRecord :: Base. Cet enregistrement actif fournit la fonction de gérer la base de données. La première méthode de User.first peut également être utilisée en héritant de cet ActiveRecord.
Le contrôleur a une structure similaire. From Rails Tutorial 6e édition https://railstutorial.jp/chapters/toy_app?version=6.0#fig-demo_controller_inheritance
Chaque contrôleur hérite d'ApplicationController et d'ApplicationController En héritant de la classe de base ActionController :: Base Vous pouvez utiliser les fonctions de base du contrôleur de la même manière avec différents contrôleurs. De plus, comme il hérite d'ApplicationController, les règles définies dans ApplicationController sont Il est appliqué dans chaque contrôleur hérité et les méthodes définies peuvent être utilisées de la même manière.
Ligne 1.1
application_controller.rb
class ApplicationController < ActionController::Base
def hello
render html:"hello,world!"
end
end
application_record.rb
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
end
Déployez l'application Toy créée dans ce chapitre sur Heroku
$ git add -A
$ git commit -m "Finish toy app"
$ git push
$ git push heroku
Si cela est laissé tel quel, une erreur se produira sur Heroku et le site ne sera pas affiché dans l'environnement de production. Suivez les journaux d'erreur sur Heroku avec les journaux heroku. Ensuite, il y a une ligne comme celle-ci.
2020-06-01T15:52:35.330114+00:00 app[web.1]: [3a72d85c-e21f-41d2-92ce-40c241660d8f]
ActionView::Template::Error (PG::UndefinedTable: ERROR: relation "users" does not exist
PG signifie PostgreSQL. Le sens est PG et il est fâché que la table des utilisateurs n'existe pas. Parce que la base de données de l'environnement de production et la base de données de l'environnement de développement sont différentes La migration doit également être effectuée dans l'environnement de production. En d'autres termes, je suis en colère parce que je n'ai pas migré.
Migrez la base de données de production avec migrate.
Cela devrait fonctionner correctement.
### Exercice
1. Si vous effectuez l'exercice précédent [2.3.3.1](https://railstutorial.jp/chapters/toy_app?version=6.0#sec-exercises_demo_user_has_many_microposts), aucun micropost ne sera enregistré dans la base de données de l'environnement de production. Pas fini
Puisqu'il va générer une erreur, supprimez la partie de code ajoutée à l'exercice, validez-la et repoussez-la.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617753/7443767e-6fa1-5f8f-900b-11470435ede0.png)
J'espère que vous pourrez créer un utilisateur comme celui-ci.
<br>
2. Il a été confirmé que les micro-messages peuvent être créés dans le même environnement de production.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617753/3dc7da5e-352e-7a75-58d4-7eb635531558.png)
3. Bien sûr, cela fonctionne
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617753/3df657eb-4246-0451-a2da-a32e358fe741.png)
[← Vers le chapitre précédent](https://qiita.com/take_webengineer/items/35ff3342ce2471e34a43)
[Vers le chapitre suivant →](https://qiita.com/take_webengineer/items/ccebe817b40b1152feba)
Recommended Posts