1 Vadovo prielaidos
Šis vadovas skirtas pradedantiesiems, kurie nori pradėti kurti Rails aplikaciją nuo nulio. Jis nenumato, kad jūs turite ankstesnį patirtį su Rails.
Rails yra internetinės aplikacijos karkasas, veikiantis Ruby programavimo kalboje. Jei neturite ankstesnės patirties su Ruby, jums gali būti labai sunku iš karto pradėti mokytis Rails. Yra keletas atrinktų internetinių išteklių sąrašų, skirtų Ruby mokymuisi:
Atkreipkite dėmesį, kad kai kurie ištekliai, nors ir puikūs, apima senesnes Ruby versijas ir gali neįtraukti kai kurių sintaksės, kurią matysite kasdieninėje Rails plėtros veikloje.
2 Kas yra Rails?
Rails yra internetinės aplikacijos kūrimo karkasas, parašytas Ruby programavimo kalba. Jis yra skirtas palengvinti internetinių aplikacijų programavimą, padarant prielaidas apie tai, ko kiekvienam programuotojui reikia pradėti. Tai leidžia rašyti mažiau kodo, tuo pačiu atliekant daugiau nei daugelis kitų kalbų ir karkasų. Patyrę Rails programuotojai taip pat praneša, kad tai daro internetinės aplikacijos kūrimą smagesnį.
Rails yra nuomonės turinti programa. Ji daro prielaidą, kad yra "geriausias" būdas daryti dalykus ir yra skirta skatinti šį būdą - ir kai kuriomis atvejais atskirti nuo alternatyvų. Jei išmoksite "Rails būdą", tikriausiai pastebėsite didelį produktyvumo padidėjimą. Jei toliau laikysitės senų įpročių iš kitų kalbų savo Rails plėtros metu ir bandysite naudoti modelius, kuriuos išmokote kitur, jūs galite turėti mažiau malonią patirtį.
Rails filosofija apima dvi pagrindines gaires:
- Nepakartokite savęs: DRY yra programinės įrangos kūrimo principas, kuris teigia, kad "kiekvienas žinių gabalas turi turėti vienintelį, aiškų, autoritetinį atvaizdą sistemoje". Nesikartodami rašydami tą pačią informaciją daug kartų, mūsų kodas yra lengviau palaikomas, plėtojamas ir mažiau klaidų.
- Konvencija virš konfigūracijos: Rails turi nuomonę apie geriausią būdą daryti daugelį dalykų internetinėje aplikacijoje ir pagal nutylėjimą naudoja šį konvencijų rinkinį, o ne reikalauja nurodyti smulkmenų per begalinius konfigūracijos failus.
3 Naujos Rails projekto sukūrimas
Geriausias būdas perskaityti šį vadovą yra sekti jį žingsnis po žingsnio. Visi žingsniai yra būtini šios pavyzdinės aplikacijos paleidimui ir nereikia jokio papildomo kodo ar žingsnių.
Sekdami šiuo vadovu, sukursite Rails projektą, vadinamą "blog", (labai) paprastą tinklaraštį. Prieš pradedant kurti aplikaciją, turite įsitikinti, kad jau įdiegėte patį Rails.
Pastaba: Žemiau pateikti pavyzdžiai naudoja $
simbolį, kad reprezentuotų jūsų terminalo įspėjimą UNIX tipo OS, nors jis gali būti pritaikytas kitaip. Jei naudojate Windows, jūsų įspėjimas atrodys kažkaip panašiai į C:\source_code>
.
3.1 Rails įdiegimas
Prieš įdiegdami Rails, turėtumėte patikrinti, ar jūsų sistema turi tinkamus priklausomybes. Tai apima:
- Ruby
- SQLite3
3.1.1 Ruby įdiegimas
Atidarykite komandinės eilutės langą. macOS atidarykite Terminal.app; Windows pasirinkite "Run" iš savo Start meniu ir įveskite cmd.exe
. Bet kokie komandos, prasidedantys dolerio ženklu $
, turėtų būti vykdomi komandinėje eilutėje. Patikrinkite, ar jau įdiegėte naujausią Ruby versiją:
$ ruby --version
ruby 2.7.0
Rails reikalauja Ruby versijos 2.7.0 arba naujesnės. Rekomenduojama naudoti naujausią Ruby versiją. Jei grąžintas versijos numeris yra mažesnis nei šis skaičius (pvz., 2.3.7 arba 1.8.7), turėsite įdiegti naują Ruby kopiją.
Norėdami įdiegti Rails Windows, pirmiausia turite įdiegti Ruby Installer.
Daugiau įdiegimo metodų daugumai operacinėms sistemoms galite rasti ruby-lang.org.
3.1.2 SQLite3 įdiegimas
Jums taip pat reikės įdiegti SQLite3 duomenų bazę.
Daugelis populiarių UNIX tipo operacinių sistemų turi tinkamą SQLite3 versiją.
Kiti gali rasti įdiegimo instrukcijas SQLite3 svetainėje.
Patikrinkite, ar jis įdiegtas teisingai ir yra jūsų apkrovos PATH
:
$ sqlite3 --version
Programa turėtų pranešti savo versiją.
3.1.3 Rails diegimas
Norėdami įdiegti Rails, naudokite gem install
komandą, kurią teikia RubyGems:
$ gem install rails
Norėdami patikrinti, ar viskas įdiegta teisingai, turėtumėte galėti paleisti šią komandą naujame terminalo lange:
$ rails --version
Jei jis rodo kažką panašaus į "Rails 7.0.0", galite tęsti.
3.2 Sukurkite tinklaraščio aplikaciją
Rails turi keletą generatorių scenarijų, kurie yra skirti palengvinti jūsų plėtros gyvenimą, sukurdami viską, kas reikalinga pradėti dirbti tam tikrą užduotį. Vienas iš jų yra naujo aplikacijos generatorius, kuris suteiks jums šviežios Rails aplikacijos pagrindą, kad neturėtumėte rašyti jos patys.
Norėdami naudoti šį generatorių, atidarykite terminalą, pereikite į katalogą, kuriame turite teises kurti failus, ir paleiskite:
$ rails new blog
Tai sukurs Rails aplikaciją, vadinamą Blog, blog
kataloge ir įdiegs Gemfile
jau minėtus priklausomybių paketus naudojant bundle install
.
PATARIMAS: Galite pamatyti visus komandų eilutės parametrus, kuriuos priima Rails aplikacijos generatorius, paleisdami rails new --help
.
Po to, kai sukūrėte tinklaraščio aplikaciją, perjunkite į jos aplanką:
$ cd blog
blog
kataloge bus keletas sukurtų failų ir aplankų, sudarančių Rails aplikacijos struktūrą. Dauguma darbo šiame vadove vyks app
aplanke, tačiau čia yra pagrindinė informacija apie kiekvieno iš pagal nutylėjimą sukurtų failų ir aplankų funkciją:
Failas/Aplankas | Paskirtis |
---|---|
app/ | Aplankas, kuriame yra jūsų aplikacijos kontroleriai, modeliai, rodiniai, pagalbininkai, pašto siuntėjai, kanalai, darbo vietos ir ištekliai. Daugiau dėmesio šiame vadove skirsite šiam aplankui. |
bin/ | Aplankas, kuriame yra rails scenarijus, kuris paleidžia jūsų aplikaciją, ir gali būti kiti scenarijai, kuriuos naudojate savo aplikacijos diegimui, atnaujinimui, išdėstymui ar paleidimui. |
config/ | Aplankas, kuriame yra konfigūracija jūsų aplikacijos maršrutams, duomenų bazėms ir kt. Apie tai išsamiau kalbama Konfigūruojant Rails aplikacijas. |
config.ru | Rack konfigūracija Rack pagrindiniams serveriams, naudojamiems paleisti aplikaciją. Daugiau informacijos apie Rack rasite Rack svetainėje. |
db/ | Aplankas, kuriame yra jūsų esama duomenų bazės schema ir duomenų bazės migracijos. |
Gemfile Gemfile.lock |
Šie failai leidžia nurodyti, kokios priklausomybės nuo paketų reikalingos jūsų Rails aplikacijai. Šiuos failus naudoja Bundler paketas. Daugiau informacijos apie Bundler rasite Bundler svetainėje. |
lib/ | Išplėstiniai moduliai jūsų aplikacijai. |
log/ | Aplikacijos žurnalo failai. |
public/ | Aplankas, kuriame yra statiniai failai ir sukompiliuoti ištekliai. Paleidus jūsų aplikaciją, šis aplankas bus prieinamas kaip yra. |
Rakefile | Šis failas randa ir įkelia užduotis, kurias galima paleisti iš komandinės eilutės. Užduočių apibrėžimai yra apibrėžti visuose Rails komponentuose. Vietoj Rakefile keitimo, savo užduotis turėtumėte pridėti pridedant failus į savo aplikacijos lib/tasks aplanką. |
README.md | Tai trumpas jūsų aplikacijos instrukcijų vadovas. Šį failą turėtumėte redaguoti, kad kitiems žmonėms būtų aišku, ką jūsų aplikacija daro, kaip ją sukonfigūruoti ir t. t. |
storage/ | Active Storage failai disko paslaugai. Apie tai išsamiau kalbama Active Storage apžvalgoje. |
test/ | Vienetų testai, fiktyvūs duomenys ir kitos testavimo priemonės. Apie tai išsamiau kalbama Rails aplikacijų testavime. |
tmp/ | Laikini failai (pvz., talpyklos ir pid failai). |
vendor/ | Vieta visam trečiųjų šalių kodui. Tipiškoje Rails aplikacijoje tai apima pardavimo paketus. |
.gitattributes | Šis failas nurodo metaduomenis tam tikriems keliose git saugykloje. Šie metaduomenys gali būti naudojami git ir kitomis priemonėmis, kad pagerintų jų veikimą. Daugiau informacijos rasite gitattributes dokumentacijoje. |
.gitignore | Šis failas nurodo git, kurie failai (ar šablonai) turėtų būti ignoruojami. Daugiau informacijos apie failų ignoravimą rasite GitHub - Ignoring files. |
.ruby-version | Šis failas nurodo numatytąją Ruby versiją. |
4 Sveiki, Rails!
Pradėkime nuo to, kad greitai atvaizduotume tekstą ekrane. Tam reikia paleisti savo Rails aplikacijos serverį.
4.1 Paleidimas
Iš tikrųjų jau turite veikiančią Rails aplikaciją. Norėdami ją pamatyti, turite paleisti interneto serverį savo plėtros mašinoje. Tai galite padaryti paleisdami šią komandą blog
aplanke:
$ bin/rails server
PATARIMAS: Jei naudojate "Windows" operacinę sistemą, skriptus reikia perduoti tiesiogiai "Ruby" interpretatoriui, pvz., ruby bin\rails server
.
PATARIMAS: "JavaScript" turinio suspaudimui reikalingas "JavaScript" vykdymo laikas jūsų sistemoje, o jo nebuvimo atveju suspaudimo metu bus rodoma "execjs" klaida. Paprastai "macOS" ir "Windows" jau turi įdiegtą "JavaScript" vykdymo laiką. "therubyrhino" yra rekomenduojamas vykdymo laikas "JRuby" naudotojams ir jis pagal numatymą pridedamas į "Gemfile" programose, kurios yra sukuriamos naudojant "JRuby". Galite išsiaiškinti visus palaikomus vykdymo laikus ExecJS svetainėje.
Tai paleis "Puma", naršyklės serverį, kuris yra numatytas "Rails". Norėdami pamatyti savo programą veikiantį, atidarykite naršyklės langą ir eikite į adresą http://localhost:3000. Turėtumėte pamatyti numatytąjį "Rails" informacijos puslapį:
Kai norite sustabdyti naršyklės serverį, spustelėkite Ctrl+C terminalo lange, kuriame jis veikia. Vystymo aplinkoje "Rails" paprastai nereikalauja paleisti serverio iš naujo; pakeitimai, kuriuos atliekate failuose, bus automatiškai aptinkami serverio.
"Rails" paleidimo puslapis yra naujos "Rails" programos "smoke test": jis užtikrina, kad jūsų programinė įranga būtų tinkamai sukonfigūruota, kad galėtų aptarnauti puslapį.
4.2 Pasakykite "Sveiki", "Rails"
Norėdami gauti pranešimą "Sveiki", "Rails", jums reikia sukurti bent jau maršrutą, valdiklį su veiksmu ir vaizdą. Maršrutas susieja užklausą su valdiklio veiksmu. Valdiklio veiksmas atlieka reikalingą darbą, kad apdorotų užklausą ir paruoštų bet kokius duomenis vaizdui. Vaizdas rodo duomenis norimu formatu.
Implementacijos požiūriu: Maršrutai yra taisyklės, parašytos "Ruby" DSL (Domain-Specific Language) kalba. Valdikliai yra "Ruby" klasės, o jų viešieji metodai yra veiksmai. O vaizdai yra šablonai, paprastai parašyti mišiniu iš HTML ir "Ruby".
Pradėkime pridedant maršrutą į mūsų maršrutų failą config/routes.rb
, viršuje esančią Rails.application.routes.draw
bloke:
Rails.application.routes.draw do
get "/articles", to: "articles#index"
# Daugiau informacijos apie šio failo DSL rasite adresu https://guides.rubyonrails.org/routing.html
end
Pirmiau pateiktas maršrutas nurodo, kad GET /articles
užklausos yra susiejamos su ArticlesController
index
veiksmu.
Norėdami sukurti ArticlesController
ir jo index
veiksmą, paleisime valdiklio generatorių (su --skip-routes
parinktimi, nes jau turime tinkamą maršrutą):
$ bin/rails generate controller Articles index --skip-routes
"Rails" sukurs kelis failus:
create app/controllers/articles_controller.rb
invoke erb
create app/views/articles
create app/views/articles/index.html.erb
invoke test_unit
create test/controllers/articles_controller_test.rb
invoke helper
create app/helpers/articles_helper.rb
invoke test_unit
Svarbiausias iš jų yra valdiklio failas app/controllers/articles_controller.rb
. Pažiūrėkime į jį:
class ArticlesController < ApplicationController
def index
end
end
index
veiksmas yra tuščias. Kai veiksmas neišreiškiamai sugeneruoja vaizdą (arba kitaip sukelia HTTP atsaką), "Rails" automatiškai sugeneruos vaizdą, kuris atitinka valdiklio ir veiksmo pavadinimą. Konvencija virš konfigūracijos! Vaizdai yra rasti app/views
kataloge. Taigi index
veiksmas pagal numatymą sugeneruos app/views/articles/index.html.erb
vaizdą.
Atidarykime app/views/articles/index.html.erb
ir pakeiskime jo turinį į:
<h1>Sveiki, Rails!</h1>
Jei anksčiau sustabdėte naršyklės serverį, kad paleistumėte valdiklio generatorių, paleiskite jį iš naujo su komanda bin/rails server
. Dabar apsilankykite adresu http://localhost:3000/articles ir pamatysite mūsų tekstą!
4.3 Nustatyti programos pagrindinį puslapį
Šiuo metu, http://localhost:3000 vis dar rodo puslapį su "Ruby on Rails" logotipu. Norėdami taip pat rodyti mūsų "Sveiki, Rails!" tekstą adresu http://localhost:3000, pridėsime maršrutą, kuris susieja mūsų programos šakninį kelią su tinkamu valdikliu ir veiksmu.
Atidarykime config/routes.rb
ir pridėkime šį root
maršrutą viršuje esančiam Rails.application.routes.draw
blokui:
Rails.application.routes.draw do
root "articles#index"
get "/articles", to: "articles#index"
end
Dabar, kai apsilankysime adresu http://localhost:3000, galėsime pamatyti mūsų "Sveiki, Rails!" tekstą, patvirtinant, kad root
maršrutas taip pat yra susietas su ArticlesController
index
veiksmu.
PATARIMAS: Norėdami sužinoti daugiau apie maršrutavimą, žiūrėkite Rails maršrutavimas iš išorės.
5 Automatinis įkėlimas
"Rails" programos nenaudoja require
funkcijos programos kodo įkėlimui.
Galbūt pastebėjote, kad ArticlesController
paveldi ApplicationController
, tačiau app/controllers/articles_controller.rb
faile nėra nieko panašaus į
require "application_controller" # NEDARYKITE TAIP.
Programos klasės ir moduliai yra prieinami visur, jums nereikia ir neturėtumėte įkelti nieko iš app
naudojant require
. Ši funkcija vadinama automatiniu įkėlimu, ir apie ją galite sužinoti daugiau Automatinis įkėlimas ir konstantų perkrovimas puslapyje.
Jums reikia tik require
iškvietimų dviems naudojimo atvejams:
- Įkelti failus iš
lib
direktorijos. - Įkelti
Gemfile
faile esančias priklausomybes, kurios turirequire: false
nustatymą.
6 MVC ir Jūs
Iki šiol mes aptarėme maršrutus, kontrolerius, veiksmus ir rodinius. Visi šie yra tipiniai internetinės programos dalys, kurios seka MVC (Model-View-Controller) modelį. MVC yra projektavimo modelis, kuris padalina programos atsakomybes tam, kad būtų lengviau suprasti. „Rails“ šį projektavimo modelį laikosi pagal konvenciją.
Kadangi turime kontrolerį ir rodinį, leiskite generuoti kitą dalį: modelį.
6.1 Modelio generavimas
Modelis yra „Ruby“ klasė, kuri naudojama duomenims reprezentuoti. Be to, modeliai gali sąveikauti su programos duomenų baze per „Rails“ funkciją, vadinamą Active Record.
Norėdami apibrėžti modelį, naudosime modelio generatorių:
$ bin/rails generate model Article title:string body:text
PASTABA: Modelio pavadinimai yra vienaskaitiniai, nes sukuriamas modelis reprezentuoja
vieną duomenų įrašą. Norint lengviau prisiminti šią konvenciją, galima pagalvoti,
kaip būtų iškviečiamas modelio konstruktorius: norime rašyti Article.new(...)
, o ne
Articles.new(...)
.
Tai sukurs keletą failų:
invoke active_record
create db/migrate/<timestamp>_create_articles.rb
create app/models/article.rb
invoke test_unit
create test/models/article_test.rb
create test/fixtures/articles.yml
Dviem failams, į kuriuos sutelksime dėmesį, yra migracijos failas
(db/migrate/<timestamp>_create_articles.rb
) ir modelio failas
(app/models/article.rb
).
6.2 Duomenų bazės migracijos
Migracijos naudojamos keisti programos duomenų bazės struktūrą. „Rails“ programose migracijos yra rašomos „Ruby“ kalba, kad jos būtų nepriklausomos nuo duomenų bazės.
Pažvelkime į naujo migracijos failo turinį:
class CreateArticles < ActiveRecord::Migration[7.0]
def change
create_table :articles do |t|
t.string :title
t.text :body
t.timestamps
end
end
end
Iškvietimas create_table
nurodo, kaip turėtų būti sukurta articles
lentelė.
Pagal numatytuosius nustatymus, create_table
metodas prideda id
stulpelį kaip
auto-incrementing pagrindinį raktą. Taigi, pirmas įrašas lentelėje turės
id
reikšmę 1, kitas įrašas turės id
reikšmę 2 ir t. t.
Blokui create_table
viduje apibrėžiami du stulpeliai: title
ir
body
. Juos pridėjo generatorius, nes juos įtraukėme į savo
generavimo komandą (bin/rails generate model Article title:string body:text
).
Blokui paskutinėje eilutėje yra iškvietimas t.timestamps
. Šis metodas apibrėžia
dar du stulpelius, vadinamus created_at
ir updated_at
. Kaip matysime,
„Rails“ juos valdys už mus, nustatys reikšmes, kai sukursime ar atnaujinsime
modelio objektą.
Paleiskime migraciją su šia komanda:
$ bin/rails db:migrate
Komanda rodo, kad lentelė buvo sukurta:
== CreateArticles: migrating ===================================
-- create_table(:articles)
-> 0.0018s
== CreateArticles: migrated (0.0018s) ==========================
PATARIMAS: Norėdami sužinoti daugiau apie migracijas, žr. Active Record migracijas.
Dabar galime sąveikauti su lentele, naudodami mūsų modelį.
6.3 Modelio naudojimas sąveikai su duomenų baze
Norėdami šiek tiek pasidžiaugti savo modeliu, naudosime „Rails“ funkciją, vadinamą
konsolė. Konsolė yra interaktyvi programavimo aplinka, panaši į irb
, bet
ji taip pat automatiškai įkelia „Rails“ ir mūsų programos kodą.
Paleiskime konsolę šia komanda:
$ bin/rails console
Turėtumėte pamatyti irb
įspėjimą:
Loading development environment (Rails 7.0.0)
irb(main):001:0>
Šiuo įspėjimu galime sukurti naują Article
objektą:
irb> article = Article.new(title: "Hello Rails", body: "I am on Rails!")
Svarbu pažymėti, kad mes tik inicijavome šį objektą. Šis objektas
dar nėra išsaugotas duomenų bazėje. Jis yra prieinamas tik konsolėje
šiuo metu. Norėdami išsaugoti objektą duomenų bazėje, turime iškviesti save
metodą:
irb> article.save
(0.1ms) begin transaction
Article Create (0.4ms) INSERT INTO "articles" ("title", "body", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["title", "Hello Rails"], ["body", "I am on Rails!"], ["created_at", "2020-01-18 23:47:30.734416"], ["updated_at", "2020-01-18 23:47:30.734416"]]
(0.9ms) commit transaction
=> true
Pirmiau pateiktame rezultate matome INSERT INTO "articles" ...
duomenų bazės užklausą. Tai
rodo, kad straipsnis buvo įterptas į mūsų lentelę. Jei vėl pažvelgsime į
article
objektą, pamatysime, kad įvyko kažkas įdomaus:
irb> article
=> #<Article id: 1, title: "Hello Rails", body: "I am on Rails!", created_at: "2020-01-18 23:47:30", updated_at: "2020-01-18 23:47:30">
id
, created_at
ir updated_at
atributai objekte dabar yra nustatyti.
Tai padarė Rails, kai išsaugojome objektą.
Kai norime gauti šį straipsnį iš duomenų bazės, galime iškviesti find
modelyje ir perduoti id
kaip argumentą:
irb> Article.find(1)
=> #<Article id: 1, title: "Hello Rails", body: "I am on Rails!", created_at: "2020-01-18 23:47:30", updated_at: "2020-01-18 23:47:30">
Ir kai norime gauti visus straipsnius iš duomenų bazės, galime iškviesti all
modelyje:
irb> Article.all
=> #<ActiveRecord::Relation [#<Article id: 1, title: "Hello Rails", body: "I am on Rails!", created_at: "2020-01-18 23:47:30", updated_at: "2020-01-18 23:47:30">]>
Ši metodas grąžina ActiveRecord::Relation
objektą, kurį
galite laikyti kaip galingą masyvą.
PATARIMAS: Norėdami sužinoti daugiau apie modelius, žiūrėkite Active Record Basics ir Active Record Query Interface.
Modeliai yra paskutinė MVC puzzle dalis. Toliau mes sujungsime visas dalis kartu.
6.4 Straipsnių sąrašo rodymas
Grįžkime į mūsų valdiklį app/controllers/articles_controller.rb
ir
pakeiskime index
veiksmą, kad gautume visus straipsnius iš duomenų bazės:
class ArticlesController < ApplicationController
def index
@articles = Article.all
end
end
Valdiklio objekto kintamieji gali būti pasiekiami per vaizdą. Tai reiškia, kad
mes galime naudoti @articles
app/views/articles/index.html.erb
faile. Atidarykime
tą failą ir pakeiskime jo turinį į:
<h1>Straipsniai</h1>
<ul>
<% @articles.each do |article| %>
<li>
<%= article.title %>
</li>
<% end %>
</ul>
Aukštyje esantis kodas yra HTML ir ERB mišinys. ERB yra šablonų sistema, kuri
vertina Ruby kodą, įterptą į dokumentą. Čia galime matyti du ERB žymių tipus: <% %>
ir <%= %>
. <% %>
žymė reiškia "įvertink įterptą Ruby kodą". <%= %>
žymė reiškia
"įvertink įterptą Ruby kodą ir išvesk jo grąžinamą reikšmę". Bet ką galite rašyti
įprasto Ruby programoje, gali būti įdėta į šias ERB žymes, nors paprastai geriausia
laikytis ERB žymių turinio trumpumo dėl skaitymo patogumo.
Kadangi mes nenorime išvesti @articles.each
grąžinamos reikšmės, mes esame
apgaubę tą kodą <% %>
. Bet, kadangi mes norime išvesti article.title
grąžinamą
reikšmę (kiekvienam straipsniui), mes esame apgaubę tą kodą <%= %>
.
Galime pamatyti galutinį rezultatą apsilankydami http://localhost:3000. (Atminkite, kad
turi būti paleistas bin/rails server
!) Čia yra kas vyksta, kai tai darome:
- Naršyklė siunčia užklausą:
GET http://localhost:3000
. - Mūsų Rails aplikacija gauna šią užklausą.
- Rails maršrutizatorius priskiria šakninį maršrutą
index
veiksmuiArticlesController
. index
veiksmas naudojaArticle
modelį, kad gautų visus straipsnius iš duomenų bazės.- Rails automatiškai atvaizduoja
app/views/articles/index.html.erb
vaizdą. - Vaizde esantis ERB kodas yra įvertinamas, kad būtų išvestas HTML.
- Serveris siunčia atsakymą, kuriame yra HTML, atgal į naršyklę.
Mes sujungėme visus MVC gabalus ir turime pirmąjį valdiklio veiksmą! Toliau pereisime prie antro veiksmo.
7 CRUDit kur tai reikalinga
Beveik visos interneto programos apima CRUD (Create, Read, Update, and Delete) operacijas. Jūs netgi galite pastebėti, kad dauguma jūsų programos darbo yra CRUD. Rails pripažįsta tai ir teikia daug funkcijų, kurios padeda supaprastinti CRUD operacijas.
Pradėkime tyrinėti šias funkcijas, pridedant daugiau funkcionalumo į mūsų programą.
7.1 Vieno straipsnio rodymas
Šiuo metu turime vaizdą, kuriame sąrašuojami visi straipsniai mūsų duomenų bazėje. Pridėkime naują vaizdą, kuriame būtų rodomas vieno straipsnio pavadinimas ir turinys.
Pradedame pridedant naują maršrutą, kuri priskiria naują valdiklio veiksmą (kurį
mes pridėsime toliau). Atidarykite config/routes.rb
ir įterpkite paskutinį rodyklės maršrutą:
Rails.application.routes.draw do
root "articles#index"
get "/articles", to: "articles#index"
get "/articles/:id", to: "articles#show"
end
Naujas maršrutas yra dar vienas get
maršrutas, bet jo kelyje yra kažkas papildomo:
:id
. Tai nurodo maršruto parametrą. Maršruto parametras užfiksuoja užklausos kelio segmentą
ir įdeda tuos reikšmes į params
Hash, kuris pasiekiamas valdiklio veiksmo. Pavyzdžiui, apdorojant
užklausą kaip GET http://localhost:3000/articles/1
, 1
būtų užfiksuota kaip reikšmė
:id
, kuri tada būtų pasiekiamas kaip params[:id]
ArticlesController
show
veiksme.
Pridėkime dabar show
veiksmą, po index
veiksmo app/controllers/articles_controller.rb
:
class ArticlesController < ApplicationController
def index
@articles = Article.all
end
def show
@article = Article.find(params[:id])
end
end
show
veiksmas iškviečia Article.find
(minėta anksčiau) su pagautu ID iš maršruto parametro. Gautas straipsnis saugomas @article
kintamajame, todėl jis pasiekiamas per rodinį. Pagal nutylėjimą, show
veiksmas atvaizduos app/views/articles/show.html.erb
.
Sukurkime app/views/articles/show.html.erb
su šiuo turiniu:
<h1><%= @article.title %></h1>
<p><%= @article.body %></p>
Dabar galime pamatyti straipsnį, kai aplankome http://localhost:3000/articles/1!
Baigiant, pridėkime patogų būdą pereiti į straipsnio puslapį. Nuorodą į kiekvieno straipsnio pavadinimą app/views/articles/index.html.erb
priešime sujungsime su jo puslapiu:
<h1>Straipsniai</h1>
<ul>
<% @articles.each do |article| %>
<li>
<a href="/articles/<%= article.id %>">
<%= article.title %>
</a>
</li>
<% end %>
</ul>
7.2 Resursinė maršrutizacija
Iki šiol aptarėme CRUD "R" (Read) dalį. Vėliau aptarsime "C" (Create), "U" (Update) ir "D" (Delete) dalis. Kaip galbūt jau supratote, tai padarysime pridedami naujus maršrutus, valdiklio veiksmus ir rodinius. Kai turime tokią maršrutų, valdiklio veiksmų ir rodinių kombinaciją, kurie kartu atlieka CRUD operacijas su viena entitete, tai vadinsime šią entitetą resursu. Pavyzdžiui, mūsų programoje straipsnis yra resursas.
Rails teikia maršrutų metodą, vadinamą resources
, kuris susieja visus konvencinius maršrutus kolekcijai resursų, pvz., straipsniams. Taigi, prieš tęsdami "C", "U" ir "D" dalis, pakeiskime dvi get
maršrutus config/routes.rb
faile į resources
:
Rails.application.routes.draw do
root "articles#index"
resources :articles
end
Galime patikrinti, kokius maršrutus susieja paleidę komandą bin/rails routes
:
$ bin/rails routes
Prefix Verb URI Pattern Controller#Action
root GET / articles#index
articles GET /articles(.:format) articles#index
new_article GET /articles/new(.:format) articles#new
article GET /articles/:id(.:format) articles#show
POST /articles(.:format) articles#create
edit_article GET /articles/:id/edit(.:format) articles#edit
PATCH /articles/:id(.:format) articles#update
DELETE /articles/:id(.:format) articles#destroy
resources
metodas taip pat sukuria URL ir kelio pagalbinės metodus, kuriais galime užtikrinti, kad mūsų kodas nepriklauso nuo konkretaus maršrutų konfigūracijos. "Prefix" stulpelyje esantys reikšmės kartu su priesaga _url
arba _path
sudaro šių pagalbinių metodų pavadinimus. Pavyzdžiui, article_path
pagalbinis metodas grąžina "/articles/#{article.id}"
, kai jam paduodamas straipsnis. Galime jį naudoti, tvarkant nuorodas app/views/articles/index.html.erb
:
<h1>Straipsniai</h1>
<ul>
<% @articles.each do |article| %>
<li>
<a href="<%= article_path(article) %>">
<%= article.title %>
</a>
</li>
<% end %>
</ul>
Tačiau dar žingsnį toliau galime eiti naudodami link_to
pagalbinį metodą. link_to
pagalbinis metodas sugeneruoja nuorodą, kurioje pirmasis argumentas yra nuorodos tekstas, o antrasis argumentas yra nuorodos paskirtis. Jei antrąjį argumentą perduodame modelio objektui, link_to
iškvies tinkamą kelio pagalbinį metodą, kad konvertuotų objektą į kelią. Pavyzdžiui, jei perduodame straipsnį, link_to
iškvies article_path
. Taigi app/views/articles/index.html.erb
tampa:
<h1>Straipsniai</h1>
<ul>
<% @articles.each do |article| %>
<li>
<%= link_to article.title, article %>
</li>
<% end %>
</ul>
Puiku!
PATARIMAS: Norėdami sužinoti daugiau apie maršrutizavimą, žiūrėkite Rails maršrutizavimas iš išorės.
7.3 Naujo straipsnio kūrimas
Dabar pereiname prie CRUD "C" (Create) dalies. Paprastai interneto programose naujo resurso kūrimas yra daugiažingsnis procesas. Pirmiausia, naudotojas prašo užpildyti formą. Tada naudotojas pateikia formą. Jei nėra klaidų, tada resursas yra sukurtas ir rodomas kažkoks patvirtinimas. Kitu atveju, forma vėl rodoma su klaidų pranešimais ir procesas kartojamas.
Rails programoje šie žingsniai konvencionaliai yra tvarkomi valdiklio new
ir create
veiksmais. Pridėkime tipinę šių veiksmų įgyvendinimą į app/controllers/articles_controller.rb
, po show
veiksmo:
class ArticlesController < ApplicationController
def index
@articles = Article.all
end
def show
@article = Article.find(params[:id])
end
def new
@article = Article.new
end
def create
@article = Article.new(title: "...", body: "...")
if @article.save
redirect_to @article
else
render :new, status: :unprocessable_entity
end
end
end
new
veiksmas sukuria naują straipsnį, bet jį neišsaugo. Šis straipsnis bus naudojamas rodinyje, kuriant formą. Pagal nutylėjimą, new
veiksmas atvaizduos app/views/articles/new.html.erb
, kurį sukursime toliau.
create
veiksmas sukuria naują straipsnį su pavadinimo ir turinio reikšmėmis ir bandys jį išsaugoti. Jei straipsnis sėkmingai išsaugotas, veiksmas nukreips naršyklę į straipsnio puslapį adresu "http://localhost:3000/articles/#{@article.id}"
.
Kitu atveju, veiksmas vėl rodo formą, atvaizduodamas app/views/articles/new.html.erb
su statuso kodu 422 Negalima vienetas.
Čia pavadinimas ir turinys yra fiktyvios reikšmės. Po to, kai sukursime formą, grįšime ir pakeisime šias reikšmes.
PASTABA: redirect_to
nukreips naršyklę į naują užklausą,
o render
atvaizduoja nurodytą vaizdą esamai užklausai.
Svarbu naudoti redirect_to
po duomenų bazės ar programos būsenos pakeitimo.
Kitu atveju, jei vartotojas atnaujins puslapį, naršyklė padarys tą pačią užklausą ir pakeitimas bus kartojamas.
7.3.1 Naudodami formos kūrėją
Naudosime „Rails“ funkciją, vadinamą formos kūrėju, kad sukurtume savo formą. Naudodami formos kūrėją, galime parašyti minimalų kodą, kad gautume formą, kuri yra visiškai sukonfigūruota ir atitinka „Rails“ konvencijas.
Sukurkime app/views/articles/new.html.erb
su šia turiniu:
<h1>Naujas straipsnis</h1>
<%= form_with model: @article do |form| %>
<div>
<%= form.label :title %><br>
<%= form.text_field :title %>
</div>
<div>
<%= form.label :body %><br>
<%= form.text_area :body %>
</div>
<div>
<%= form.submit %>
</div>
<% end %>
form_with
pagalbinės funkcijos metodas sukuria formos kūrėją. form_with
bloke kviečiame
label
ir text_field
metodus iš formos kūrėjo, kad gautume tinkamus formos elementus.
Gautas rezultatas iš mūsų form_with
kvietimo atrodys taip:
<form action="/articles" accept-charset="UTF-8" method="post">
<input type="hidden" name="authenticity_token" value="...">
<div>
<label for="article_title">Pavadinimas</label><br>
<input type="text" name="article[title]" id="article_title">
</div>
<div>
<label for="article_body">Turinys</label><br>
<textarea name="article[body]" id="article_body"></textarea>
</div>
<div>
<input type="submit" name="commit" value="Sukurti straipsnį" data-disable-with="Sukurti straipsnį">
</div>
</form>
PATARIMAS: Norėdami sužinoti daugiau apie formos kūrėjus, žr. Veiksmo vaizdo formos pagalbininkai.
7.3.2 Naudodami stipriuosius parametrus
Pateikti formos duomenys yra įdedami į params
objektą, kartu su užfiksuotais maršruto
parametrais. Taigi, create
veiksmas gali pasiekti pateiktą pavadinimą per
params[:article][:title]
ir pateiktą turinį per params[:article][:body]
.
Galėtume perduoti šias reikšmes atskirai į Article.new
, bet tai būtų
daug žodžių ir gali būti klaidinga. Ir tai dar labiau pablogės, pridėjus daugiau
laukų.
Vietoj to, perduosime vieną Hash
, kuriame bus šios reikšmės. Tačiau vis tiek turime
nurodyti, kokios reikšmės yra leidžiamos tame Hash
. Kitu atveju, kenksmingas vartotojas
galėtų pateikti papildomus formos laukus ir perrašyti privačią informaciją. Iš tikrųjų,
jei perduosime neatfiltruotą params[:article]
Hash
tiesiogiai į Article.new
,
„Rails“ mums praneš apie šią problemą, iškeliant ForbiddenAttributesError
.
Todėl naudosime „Rails“ funkciją, vadinamą stipriaisiais parametrais, kad filtruotume params
.
Galima tai laikyti kaip stiprųjį tipavimą
params
atžvilgiu.
Pridėkime privačią metodą į app/controllers/articles_controller.rb
apačią, kuris filtruos params
. Ir pakeiskime create
veiksmą,
kad jis jį naudotų:
class ArticlesController < ApplicationController
def index
@articles = Article.all
end
def show
@article = Article.find(params[:id])
end
def new
@article = Article.new
end
def create
@article = Article.new(article_params)
if @article.save
redirect_to @article
else
render :new, status: :unprocessable_entity
end
end
private
def article_params
params.require(:article).permit(:title, :body)
end
end
PATARIMAS: Norėdami sužinoti daugiau apie stipriuosius parametrus, žr. Veiksmo kontrolerio apžvalga § Stiprieji parametrai.
7.3.3 Validacija ir klaidų pranešimų rodymas
Kaip matėme, resurso kūrimas yra daugiaužimtis procesas. Neleistinos
vartotojo įvesties tvarkymas yra dar vienas to proceso žingsnis. „Rails“ suteikia funkciją, vadinamą
validacijomis, kad padėtų mums susidoroti su neleistina vartotojo įvestimi. Validacijos yra taisyklės,
kurios yra tikrinamos prieš išsaugant modelio objektą. Jei patikrinimai nepavyksta, išsaugojimas bus nutrauktas,
ir atitinkami klaidų pranešimai bus pridėti prie modelio objekto errors
atributo.
Pridėkime keletą validacijų į mūsų modelį app/models/article.rb
:
class Article < ApplicationRecord
validates :title, presence: true
validates :body, presence: true, length: { minimum: 10 }
end
Pirma validacija nurodo, kad title
reikšmė turi būti pateikta. Kadangi
title
yra eilutė, tai reiškia, kad title
reikšmė turi turėti bent vieną
nebaltąjį simbolį.
Antra validacija nurodo, kad body
reikšmė taip pat turi būti pateikta.
Be to, ji nurodo, kad body
reikšmė turi būti bent 10 simbolių ilgio.
PASTABA: Galbūt klausiatės, kur yra apibrėžti title
ir body
atributai.
„Active Record“ automatiškai apibrėžia modelio atributus kiekvienam lentelės stulpeliui,
todėl jums nereikia deklaruoti šių atributų savo modelio faile.
Su mūsų patvirtinimais vietose, pakeiskime app/views/articles/new.html.erb
failą, kad rodytų bet kokius klaidų pranešimus title
ir body
:
<h1>Naujas straipsnis</h1>
<%= form_with model: @article do |form| %>
<div>
<%= form.label :title %><br>
<%= form.text_field :title %>
<% @article.errors.full_messages_for(:title).each do |message| %>
<div><%= message %></div>
<% end %>
</div>
<div>
<%= form.label :body %><br>
<%= form.text_area :body %><br>
<% @article.errors.full_messages_for(:body).each do |message| %>
<div><%= message %></div>
<% end %>
</div>
<div>
<%= form.submit %>
</div>
<% end %>
full_messages_for
metodas grąžina vartotojui draugiškus klaidų pranešimus nurodytam atributui. Jei nėra klaidų šiam atributui, masyvas bus tuščias.
Norint suprasti, kaip visa tai veikia kartu, pažvelkime į new
ir create
kontrolerio veiksmus:
def new
@article = Article.new
end
def create
@article = Article.new(article_params)
if @article.save
redirect_to @article
else
render :new, status: :unprocessable_entity
end
end
Kai aplankome http://localhost:3000/articles/new, GET /articles/new
užklausa yra susiejama su new
veiksmu. new
veiksmas nesistengia išsaugoti
@article
. Todėl validacijos nėra tikrinamos ir nebus klaidų pranešimų.
Kai pateikiame formą, POST /articles
užklausa yra susiejama su create
veiksmu. create
veiksmas bando išsaugoti @article
. Todėl validacijos yra
tikrinamos. Jei kuri nors validacija nepavyksta, @article
nebus išsaugotas ir
app/views/articles/new.html.erb
bus rodomas su klaidų pranešimais.
PATARIMAS: Norėdami sužinoti daugiau apie validacijas, žiūrėkite Active Record Validations. Norėdami sužinoti daugiau apie validacijos klaidų pranešimus, žiūrėkite Active Record Validations § Darbas su validacijos klaidomis.
7.3.4 Baigimas
Dabar galime sukurti straipsnį, aplankydami http://localhost:3000/articles/new.
Baigiant darbą, pridėkime nuorodą į šį puslapį apačioje
app/views/articles/index.html.erb
:
<h1>Straipsniai</h1>
<ul>
<% @articles.each do |article| %>
<li>
<%= link_to article.title, article %>
</li>
<% end %>
</ul>
<%= link_to "Naujas straipsnis", new_article_path %>
7.4 Straipsnio atnaujinimas
Mes jau aptarėme CRUD "CR" dalį. Dabar eikime prie "U" (Atnaujinimas). Resurso atnaujinimas yra labai panašus į resurso kūrimą. Abu procesai yra daugiausiai etapai. Pirmiausia, vartotojas prašo formos redaguoti duomenis. Tada vartotojas pateikia formą. Jei nėra klaidų, tada resursas yra atnaujinamas. Kitu atveju, forma vėl rodoma su klaidų pranešimais ir procesas kartojamas.
Šie žingsniai konvencionaliai yra tvarkomi per kontrolerio edit
ir update
veiksmus. Pridėkime tipinį šių veiksmų įgyvendinimą į app/controllers/articles_controller.rb
, po create
veiksmo:
class ArticlesController < ApplicationController
def index
@articles = Article.all
end
def show
@article = Article.find(params[:id])
end
def new
@article = Article.new
end
def create
@article = Article.new(article_params)
if @article.save
redirect_to @article
else
render :new, status: :unprocessable_entity
end
end
def edit
@article = Article.find(params[:id])
end
def update
@article = Article.find(params[:id])
if @article.update(article_params)
redirect_to @article
else
render :edit, status: :unprocessable_entity
end
end
private
def article_params
params.require(:article).permit(:title, :body)
end
end
Pastebėkite, kaip edit
ir update
veiksmai panašūs į new
ir create
veiksmus.
edit
veiksmas gauna straipsnį iš duomenų bazės ir jį saugo @article
, kad jis galėtų būti naudojamas kuriant formą. Pagal numatytuosius nustatymus, edit
veiksmas rodo app/views/articles/edit.html.erb
.
update
veiksmas (vėl) gauna straipsnį iš duomenų bazės ir bandys jį atnaujinti su pateikta forma, kurią filtruoja article_params
. Jei nėra jokių validacijos klaidų ir atnaujinimas pavyksta, veiksmas nukreipia naršyklę į straipsnio puslapį. Kitu atveju, veiksmas vėl rodo formą - su klaidų pranešimais - per app/views/articles/edit.html.erb
.
7.4.1 Dalijimosi vaizdo kodo naudojimas naudojant dalis
Mūsų edit
forma atrodys taip pat kaip ir new
forma. Net kodas bus tas pats, dėka "Rails" formos kūrėjo ir resursų maršrutizavimo. Formos kūrėjas automatiškai konfigūruoja formą, kad ji atliktų tinkamą užklausos rūšį, remiantis tuo, ar modelio objektas buvo anksčiau išsaugotas.
Kadangi kodas bus tas pats, išskirsime jį į bendrą vaizdą, vadinamą dalimi. Sukurkime app/views/articles/_form.html.erb
su šiais turiniais:
<%= form_with model: article do |form| %>
<div>
<%= form.label :title %><br>
<%= form.text_field :title %>
<% article.errors.full_messages_for(:title).each do |message| %>
<div><%= message %></div>
<% end %>
</div>
<div>
<%= form.label :body %><br>
<%= form.text_area :body %><br>
<% article.errors.full_messages_for(:body).each do |message| %>
<div><%= message %></div>
<% end %>
</div>
<div>
<%= form.submit %>
</div>
<% end %>
Pirmiau pateiktas kodas yra tas pats kaip ir mūsų forma app/views/articles/new.html.erb
, išskyrus tai, kad visi @article
pasikartojimai buvo pakeisti į article
. Kadangi daliniai yra bendrinis kodas, geriausia praktika yra tai, kad jie nepriklauso nuo konkrečių kintamųjų, nustatytų valdiklio veiksmo. Vietoj to, perduosime straipsnį dalinei kaip vietinį kintamąjį.
Atnaujinkime app/views/articles/new.html.erb
, kad naudotų dalinį per render
:
<h1>Naujas straipsnis</h1>
<%= render "form", article: @article %>
PASTABA: Dalinio failo pavadinimas turi būti pradėtas su pabraukimu, pvz.
_form.html.erb
. Tačiau jį renderinant, jis yra paminėtas be pabraukimo, pvz.
render "form"
.
Ir dabar, sukursime labai panašų app/views/articles/edit.html.erb
:
<h1>Redaguoti straipsnį</h1>
<%= render "form", article: @article %>
PATARIMAS: Norėdami sužinoti daugiau apie dalinius, žr. Išdėstymai ir atvaizdavimas „Rails“ § Naudoti dalinius.
7.4.2 Baigiant
Dabar galime atnaujinti straipsnį apsilankydami jo redagavimo puslapyje, pvz.
http://localhost:3000/articles/1/edit. Baigiant, pridėkime nuorodą į redagavimo
puslapį apačioje app/views/articles/show.html.erb
:
<h1><%= @article.title %></h1>
<p><%= @article.body %></p>
<ul>
<li><%= link_to "Redaguoti", edit_article_path(@article) %></li>
</ul>
7.5 Straipsnio trynimas
Galų gale, pasiekėme „D“ (Trinti) CRUD. Resurso trynimas yra paprastesnis
procesas nei kūrimas ar atnaujinimas. Jis reikalauja tik maršruto ir valdiklio
veiksmo. Ir mūsų resursinė maršrutizacija (resources :articles
) jau teikia
maršrutą, kuris susiejamas su destroy
veiksmu ArticlesController
.
Taigi, pridėkime įprastą destroy
veiksmą į app/controllers/articles_controller.rb
,
po update
veiksmo:
class ArticlesController < ApplicationController
def index
@articles = Article.all
end
def show
@article = Article.find(params[:id])
end
def new
@article = Article.new
end
def create
@article = Article.new(article_params)
if @article.save
redirect_to @article
else
render :new, status: :unprocessable_entity
end
end
def edit
@article = Article.find(params[:id])
end
def update
@article = Article.find(params[:id])
if @article.update(article_params)
redirect_to @article
else
render :edit, status: :unprocessable_entity
end
end
def destroy
@article = Article.find(params[:id])
@article.destroy
redirect_to root_path, status: :see_other
end
private
def article_params
params.require(:article).permit(:title, :body)
end
end
destroy
veiksmas gauna straipsnį iš duomenų bazės ir iškviečia destroy
metodą. Tada jis nukreipia naršyklę į pagrindinį puslapį su statuso kodu
303 See Other.
Pasirinkome nukreipti į pagrindinį puslapį, nes tai yra pagrindinis mūsų prieigos
taškas straipsniams. Tačiau kitais atvejais galite nuspręsti nukreipti į
pvz. articles_path
.
Dabar pridėkime nuorodą apačioje app/views/articles/show.html.erb
, kad galėtume
ištrinti straipsnį iš jo pačio puslapio:
<h1><%= @article.title %></h1>
<p><%= @article.body %></p>
<ul>
<li><%= link_to "Redaguoti", edit_article_path(@article) %></li>
<li><%= link_to "Ištrinti", article_path(@article), data: {
turbo_method: :delete,
turbo_confirm: "Ar tikrai?"
} %></li>
</ul>
Pirmiau pateiktame kode naudojame data
parinktį, kad nustatytume „Destroy“ nuorodos
data-turbo-method
ir data-turbo-confirm
HTML atributus. Abu šie atributai yra
susieti su Turbo, kuris yra įtrauktas pagal
numatytuosius nustatymus naujuose „Rails“ programose. data-turbo-method="delete"
sukels DELETE
užklausą vietoje GET
užklausos. data-turbo-confirm="Ar tikrai?"
sukels patvirtinimo dialogo langą, kai paspaudžiama nuoroda. Jei vartotojas atšaukia
dialogą, užklausa bus nutraukta.
Ir tai viskas! Dabar galime sąrašuoti, rodyti, kurti, atnaujinti ir trinti straipsnius! InCRUDable!
8 Antrinio modelio pridėjimas
Atėjo laikas pridėti antrinį modelį į programą. Antrasis modelis bus skirtas komentarams straipsniuose tvarkyti.
8.1 Modelio generavimas
Matysime tą patį generatorių, kurį naudojome anksčiau, kai kūrėme
Article
modelį. Šį kartą sukursime Comment
modelį, kuriame bus saugoma
nuoroda į straipsnį. Paleiskite šią komandą terminalo lange:
$ bin/rails generate model Comment commenter:string body:text article:references
Ši komanda sugeneruos keturis failus:
Failas | Paskirtis |
---|---|
db/migrate/20140120201010_create_comments.rb | Migracija, skirta sukurti komentarų lentelę duomenų bazėje (Jūsų pavadinime bus kitokia laiko žymė) |
app/models/comment.rb | Komentaro modelis |
test/models/comment_test.rb | Testavimo pagalba komentaro modeliui |
test/fixtures/comments.yml | Pavyzdiniai komentarai testavimui |
Pirmiausia, pažiūrėkite į app/models/comment.rb
:
class Comment < ApplicationRecord
belongs_to :article
end
Tai labai panašu į Article
modelį, kurį matėte anksčiau. Skirtumas
yra eilutė belongs_to :article
, kuri nustato „Active Record“ asociaciją.
Apie asociacijas sužinosite šio vadovo kitame skyriuje.
(:references
) raktažodis, naudojamas shell komandoje, yra specialus modelio duomenų tipas.
Tai sukuria naują stulpelį jūsų duomenų bazės lentelėje su pateiktu modelio pavadinimu, prie kurio pridedamas _id
ir gali laikyti sveikus skaičius. Norėdami geriau suprasti, analizuokite
db/schema.rb
failą po migracijos paleidimo.
Be modelio, „Rails“ taip pat sukūrė migraciją, kad sukurtų atitinkamą duomenų bazės lentelę:
class CreateComments < ActiveRecord::Migration[7.0]
def change
create_table :comments do |t|
t.string :commenter
t.text :body
t.references :article, null: false, foreign_key: true
t.timestamps
end
end
end
t.references
eilutė sukuria sveikąjį stulpelį, vadinamą article_id
, indeksą
jam ir užsienio raktų apribojimą, rodantį į articles
lentelės id
stulpelį. Tęskite ir paleiskite migraciją:
$ bin/rails db:migrate
„Rails“ pakankamai protingas, kad vykdytų tik migracijas, kurios dar nebuvo paleistos dabartinėje duomenų bazėje, todėl šiuo atveju matysite tik:
== CreateComments: migrating =================================================
-- create_table(:comments)
-> 0.0115s
== CreateComments: migrated (0.0119s) ========================================
8.2 Modelių susiejimas
„Active Record“ asociacijos leidžia lengvai nurodyti ryšį tarp dviejų modelių. Komentarų ir straipsnių atveju galėtumėte aprašyti ryšius taip:
- Kiekvienas komentaras priklauso vienam straipsniui.
- Vienas straipsnis gali turėti daug komentarų.
Iš tikrųjų tai labai arti sintaksės, kurią „Rails“ naudoja, kad nurodytų šį
asociaciją. Jau matėte eilutę kodo viduje Comment
modelyje
(app/models/comment.rb), kuri nurodo, kad kiekvienas komentaras priklauso straipsniui:
class Comment < ApplicationRecord
belongs_to :article
end
Turėsite redaguoti app/models/article.rb
, kad pridėtumėte asociacijos kitą pusę:
class Article < ApplicationRecord
has_many :comments
validates :title, presence: true
validates :body, presence: true, length: { minimum: 10 }
end
Šios dvi deklaracijos įgalina daug automatinės veiklos. Pavyzdžiui, jei
turite egzempliorių @article
, kuriame yra straipsnis, galite gauti
visus komentarus, priklausančius tam straipsniui, kaip masyvą naudodami
@article.comments
.
PATARIMAS: Daugiau informacijos apie „Active Record“ asociacijas rasite „Active Record“ asociacijų vadove.
8.3 Komentarų maršruto pridėjimas
Kaip ir su articles
valdikliu, turėsime pridėti maršrutą, kad „Rails“
žinotų, kur norime eiti, kad pamatytume comments
. Vėl atidarykite
config/routes.rb
failą ir jį redaguokite taip:
Rails.application.routes.draw do
root "articles#index"
resources :articles do
resources :comments
end
end
Tai sukuria comments
kaip sugrupuotą resursą articles
viduje. Tai
yra dar viena dalis, kuri užfiksuoja hierarchinį ryšį tarp
straipsnių ir komentarų.
PATARIMAS: Daugiau informacijos apie maršrutizavimą rasite „Rails“ maršrutizavimo vadove.
8.4 Valdiklio generavimas
Turėdami modelį, galite atkreipti dėmesį į atitinkamą valdiklio sukūrimą. Vėl naudosime tą patį generatorių, kurį naudojome anksčiau:
$ bin/rails generate controller Comments
Tai sukuria tris failus ir vieną tuščią katalogą:
Failas/Katalogas | Paskirtis |
---|---|
app/controllers/comments_controller.rb | Komentarų valdiklis |
app/views/comments/ | Valdiklio rodiniai saugomi čia |
test/controllers/comments_controller_test.rb | Valdiklio testas |
app/helpers/comments_helper.rb | Rodinio pagalbinis failas |
Kaip ir su bet kuriu tinklaraščiu, mūsų skaitytojai sukurs savo komentarus tiesiogiai po
straipsnio perskaitymo ir pridėję savo komentarą, bus nukreipti atgal
į straipsnio rodinio puslapį, kad pamatytų savo komentarą sąraše. Dėl šios priežasties
CommentsController
yra skirtas suteikti metodą komentarų kūrimui ir šlamšto komentarų trynimui, kai jie atkeliauja.
Taigi, pirma, sukonfigūruosime straipsnio rodinio šabloną
(app/views/articles/show.html.erb
), kad galėtume sukurti naują komentarą:
<h1><%= @article.title %></h1>
<p><%= @article.body %></p>
<ul>
<li><%= link_to "Edit", edit_article_path(@article) %></li>
<li><%= link_to "Destroy", article_path(@article), data: {
turbo_method: :delete,
turbo_confirm: "Are you sure?"
} %></li>
</ul>
<h2>Add a comment:</h2>
<%= form_with model: [ @article, @article.comments.build ] do |form| %>
<p>
<%= form.label :commenter %><br>
<%= form.text_field :commenter %>
</p>
<p>
<%= form.label :body %><br>
<%= form.text_area :body %>
</p>
<p>
<%= form.submit %>
</p>
<% end %>
Tai prideda formą į Article
rodinio puslapį, kuri sukuria naują komentarą,
kviečiant CommentsController
create
veiksmą. Čia form_with
kvietimas naudoja
masyvą, kuris sukurs sugrupuotą maršrutą, pvz., /articles/1/comments
.
Prijunkime create
metodą app/controllers/comments_controller.rb
:
class CommentsController < ApplicationController
def create
@article = Article.find(params[:article_id])
@comment = @article.comments.create(comment_params)
redirect_to article_path(@article)
end
private
def comment_params
params.require(:comment).permit(:commenter, :body)
end
end
Čia matysite šiek tiek daugiau sudėtingumo nei straipsnių valdiklyje. Tai yra šalutinis efektas, kurį sukėlė jūsų sukurtas įdėklas. Kiekvienas komentaro užklausa turi sekti straipsnį, prie kurio pridedamas komentaras, todėl pradinis kvietimas find
metode Article
modelyje gauna klausiamą straipsnį.
Be to, kodas pasinaudoja kai kuriomis asociacijos metodais. Mes naudojame create
metodą @article.comments
objekte, kad sukurtume ir išsaugotume komentarą. Tai automatiškai susieja komentarą su tuo konkretaus straipsnio objektu.
Kai sukūrėme naują komentarą, nukreipiame vartotoją atgal į pradinį straipsnį naudodami article_path(@article)
pagalbinį metodą. Kaip jau matėme, tai iškviečia show
veiksmą ArticlesController
, kuris vėlgi atvaizduoja show.html.erb
šabloną. Čia norime, kad komentaras būtų rodomas, todėl pridėkime jį prie app/views/articles/show.html.erb
.
<h1><%= @article.title %></h1>
<p><%= @article.body %></p>
<ul>
<li><%= link_to "Redaguoti", edit_article_path(@article) %></li>
<li><%= link_to "Naikinti", article_path(@article), data: {
turbo_method: :delete,
turbo_confirm: "Ar tikrai?"
} %></li>
</ul>
<h2>Komentarai</h2>
<% @article.comments.each do |comment| %>
<p>
<strong>Komentuotojas:</strong>
<%= comment.commenter %>
</p>
<p>
<strong>Komentaras:</strong>
<%= comment.body %>
</p>
<% end %>
<h2>Pridėti komentarą:</h2>
<%= form_with model: [ @article, @article.comments.build ] do |form| %>
<p>
<%= form.label :commenter %><br>
<%= form.text_field :commenter %>
</p>
<p>
<%= form.label :body %><br>
<%= form.text_area :body %>
</p>
<p>
<%= form.submit %>
</p>
<% end %>
Dabar galite pridėti straipsnius ir komentarus į savo tinklaraštį ir matyti juos tinkamuose vietose.
9 Refaktorizavimas
Dabar, kai turime veikiančius straipsnius ir komentarus, pažvelkime į app/views/articles/show.html.erb
šabloną. Jis tampa ilgas ir neįmanomas. Galime naudoti dalinius šablonus, kad jį sutvarkytume.
9.1 Dalinių kolekcijų atvaizdavimas
Pirmiausia, sukursime dalinį šabloną komentarų atvaizdavimui. Sukurkite failą app/views/comments/_comment.html.erb
ir įrašykite į jį šį kodą:
<p>
<strong>Komentuotojas:</strong>
<%= comment.commenter %>
</p>
<p>
<strong>Komentaras:</strong>
<%= comment.body %>
</p>
Tada galite pakeisti app/views/articles/show.html.erb
šabloną taip:
<h1><%= @article.title %></h1>
<p><%= @article.body %></p>
<ul>
<li><%= link_to "Redaguoti", edit_article_path(@article) %></li>
<li><%= link_to "Naikinti", article_path(@article), data: {
turbo_method: :delete,
turbo_confirm: "Ar tikrai?"
} %></li>
</ul>
<h2>Komentarai</h2>
<%= render @article.comments %>
<h2>Pridėti komentarą:</h2>
<%= form_with model: [ @article, @article.comments.build ] do |form| %>
<p>
<%= form.label :commenter %><br>
<%= form.text_field :commenter %>
</p>
<p>
<%= form.label :body %><br>
<%= form.text_area :body %>
</p>
<p>
<%= form.submit %>
</p>
<% end %>
Tai dabar atvaizduos dalinį šabloną app/views/comments/_comment.html.erb
vieną kartą kiekvienam komentarui, esančiam @article.comments
kolekcijoje. Kai render
metodas iteruoja per @article.comments
kolekciją, jis priskiria kiekvieną komentarą vietinei kintamajai, pavadintai taip pat kaip dalinis šablonas, šiuo atveju comment
, kuris tada yra prieinamas daliniame šablone.
9.2 Dalinio formos atvaizdavimas
Taip pat perkelsime naujo komentaro sekciją į atskirą dalinį šabloną. Vėlgi, sukuriame failą app/views/comments/_form.html.erb
, kuriame yra šis kodas:
<%= form_with model: [ @article, @article.comments.build ] do |form| %>
<p>
<%= form.label :commenter %><br>
<%= form.text_field :commenter %>
</p>
<p>
<%= form.label :body %><br>
<%= form.text_area :body %>
</p>
<p>
<%= form.submit %>
</p>
<% end %>
Tada pakeiskime app/views/articles/show.html.erb
šabloną taip:
<h1><%= @article.title %></h1>
<p><%= @article.body %></p>
<ul>
<li><%= link_to "Redaguoti", edit_article_path(@article) %></li>
<li><%= link_to "Naikinti", article_path(@article), data: {
turbo_method: :delete,
turbo_confirm: "Ar tikrai?"
} %></li>
</ul>
<h2>Komentarai</h2>
<%= render @article.comments %>
<h2>Pridėti komentarą:</h2>
<%= render 'comments/form' %>
Antrasis render
tiesiog nurodo dalinį šabloną, kurį norime atvaizduoti, comments/form
. „Rails“ pakankamai protingas, kad pastebėtų šioje eilutėje esantį pasvirąjį brūkšnį ir suprastų, kad norite atvaizduoti _form.html.erb
failą app/views/comments
kataloge.
@article
objektas yra prieinamas visiems daliniams šablonams, kurie yra atvaizduojami peržiūros metu, nes jį apibrėžėme kaip objekto kintamąjį.
9.3 Naudojant susirūpinimus
Susirūpinimai yra būdas padaryti didelius valdiklius ar modelius lengviau suprasti ir tvarkyti. Tai taip pat turi privalumą, kai kelios modeliai (arba valdikliai) dalijasi tais pačiais susirūpinimais. Susirūpinimai yra įgyvendinami naudojant modulius, kuriuose yra metodai, atitinkantys gerai apibrėžtą modelio ar valdiklio funkcionalumo dalį. Kitose kalbose moduliai dažnai žinomi kaip mišiniai.
Galite naudoti susirūpinimus savo valdiklyje arba modelyje taip pat, kaip naudotumėte bet kurį modulį. Kai pirmą kartą sukūrėte savo programą su rails new blog
, kartu su kitais buvo sukurti du aplankai app/
:
app/controllers/concerns
app/models/concerns
Pavyzdyje žemiau įgyvendinsime naują funkciją mūsų tinklaraščiui, kuris gautų naudos naudojant susirūpinimus. Tada sukursime susirūpinimą ir pertvarkysime kodą, kad jį naudotume, padarant kodą saugesnį ir lengviau palaikomą.
Tinklaraščio straipsnis gali turėti įvairių būsenų - pavyzdžiui, jis gali būti matomas visiems (t.y. public
), arba tik autoriui (t.y. private
). Jis taip pat gali būti paslėptas visiems, bet vis tiek pasiekiamas (t.y. archived
). Komentarai taip pat gali būti paslėpti arba matomi. Tai galima atvaizduoti naudojant status
stulpelį kiekviename modelyje.
Pirmiausia, paleiskime šias migracijas, kad pridėtume status
į Articles
ir Comments
:
$ bin/rails generate migration AddStatusToArticles status:string
$ bin/rails generate migration AddStatusToComments status:string
Tada atnaujinkime duomenų bazę sukurtais migracijomis:
$ bin/rails db:migrate
Norėdami pasirinkti būseną esamiems straipsniams ir komentarams, galite pridėti numatytąją reikšmę sukurtų migracijų failams, pridėdami default: "public"
parinktį ir paleisdami migracijas dar kartą. Taip pat galite iškviesti Article.update_all(status: "public")
ir Comment.update_all(status: "public")
per rails console
.
PATARIMAS: Norėdami sužinoti daugiau apie migracijas, žr. Active Record migracijas.
Taip pat turime leisti :status
raktą kaip dalį stipriųjų parametrų, app/controllers/articles_controller.rb
:
private
def article_params
params.require(:article).permit(:title, :body, :status)
end
ir app/controllers/comments_controller.rb
:
private
def comment_params
params.require(:comment).permit(:commenter, :body, :status)
end
Po to, article
modelyje, paleidus migraciją, kad pridėtume status
stulpelį naudojant bin/rails db:migrate
komandą, pridėtume:
class Article < ApplicationRecord
has_many :comments
validates :title, presence: true
validates :body, presence: true, length: { minimum: 10 }
VALID_STATUSES = ['public', 'private', 'archived']
validates :status, inclusion: { in: VALID_STATUSES }
def archived?
status == 'archived'
end
end
ir Comment
modelyje:
class Comment < ApplicationRecord
belongs_to :article
VALID_STATUSES = ['public', 'private', 'archived']
validates :status, inclusion: { in: VALID_STATUSES }
def archived?
status == 'archived'
end
end
Tada, mūsų index
veiksmo šablone (app/views/articles/index.html.erb
) naudotume archived?
metodą, kad nebūtų rodomas joks straipsnis, kuris yra archyvuotas:
<h1>Straipsniai</h1>
<ul>
<% @articles.each do |article| %>
<% unless article.archived? %>
<li>
<%= link_to article.title, article %>
</li>
<% end %>
<% end %>
</ul>
<%= link_to "Naujas straipsnis", new_article_path %>
Panašiai, mūsų komentaro daliniame rodinyje (app/views/comments/_comment.html.erb
) naudotume archived?
metodą, kad nebūtų rodomas joks komentaras, kuris yra archyvuotas:
<% unless comment.archived? %>
<p>
<strong>Komentuotojas:</strong>
<%= comment.commenter %>
</p>
<p>
<strong>Komentaras:</strong>
<%= comment.body %>
</p>
<% end %>
Tačiau jei vėl pažvelgsite į mūsų modelius, pamatysite, kad logika yra dubliuota. Jei ateityje padidinsime savo tinklaraščio funkcionalumą - pavyzdžiui, įtrauksime privačius pranešimus - galime vėl rasti save dubliuojant logiką. Tai yra vieta, kur naudingi susirūpinimai.
Susirūpinimas yra atsakingas tik už modelio atsakomybės fokusu; mūsų susirūpinimo metoduose visi susiję su modelio matomumu. Pavadinkime savo naują susirūpinimą (modulį) Visible
. Galime sukurti naują failą app/models/concerns
aplankale, vadinamą visible.rb
, ir saugoti visus dubliuotus metodus, kurie buvo modeliuose.
app/models/concerns/visible.rb
module Visible
def archived?
status == 'archived'
end
end
Galime pridėti savo būsenos patikrinimą prie susirūpinimo, bet tai šiek tiek sudėtingesnis procesas, nes patikrinimai yra metodai, kurie yra kviečiami klasės lygyje. ActiveSupport::Concern
(API vadovas) suteikia paprastesnį būdą juos įtraukti:
module Visible
extend ActiveSupport::Concern
VALID_STATUSES = ['public', 'private', 'archived']
included do
validates :status, inclusion: { in: VALID_STATUSES }
end
def archived?
status == 'archived'
end
end
Dabar galime pašalinti dubliuotą logiką iš kiekvieno modelio ir vietoj to įtraukti mūsų naują Visible
modulį:
app/models/article.rb
:
class Article < ApplicationRecord
include Visible
has_many :comments
validates :title, presence: true
validates :body, presence: true, length: { minimum: 10 }
end
ir app/models/comment.rb
:
class Comment < ApplicationRecord
include Visible
belongs_to :article
end
Klasės metodai taip pat gali būti pridėti prie susirūpinimų. Jei norime rodyti viešų straipsnių ar komentarų skaičių pagrindiniame puslapyje, galime pridėti klasės metodą prie Visible kaip parodyta žemiau:
module Visible
extend ActiveSupport::Concern
VALID_STATUSES = ['public', 'private', 'archived']
included do
validates :status, inclusion: { in: VALID_STATUSES }
end
class_methods do
def public_count
where(status: 'public').count
end
end
def archived?
status == 'archived'
end
end
Tada peržiūroje jį galite iškviesti kaip bet kurį klasės metodą:
<h1>Straipsniai</h1>
Mūsų tinklaraštyje yra <%= Article.public_count %> straipsniai ir skaičiuojama!
<ul>
<% @articles.each do |article| %>
<% unless article.archived? %>
<li>
<%= link_to article.title, article %>
</li>
<% end %>
<% end %>
</ul>
<%= link_to "Naujas straipsnis", new_article_path %>
Baigiant, pridėsime pasirinkimo laukelį formoms ir leisime vartotojui pasirinkti būseną, kai jis kuria naują straipsnį ar skelbia naują komentarą. Taip pat galime nurodyti numatytąją būseną kaip public
. app/views/articles/_form.html.erb
faile galime pridėti:
<div>
<%= form.label :status %><br>
<%= form.select :status, ['public', 'private', 'archived'], selected: 'public' %>
</div>
ir app/views/comments/_form.html.erb
faile:
<p>
<%= form.label :status %><br>
<%= form.select :status, ['public', 'private', 'archived'], selected: 'public' %>
</p>
10 Komentarų trynimas
Kitas svarbus tinklaraščio funkcionalumas yra galimybė ištrinti šlamšto komentarus. Tam reikia įgyvendinti nuorodą peržiūroje ir destroy
veiksmą CommentsController
.
Taigi, pirmiausia pridėkime trynimo nuorodą į app/views/comments/_comment.html.erb
dalinį:
<% unless comment.archived? %>
<p>
<strong>Komentuotojas:</strong>
<%= comment.commenter %>
</p>
<p>
<strong>Komentaras:</strong>
<%= comment.body %>
</p>
<p>
<%= link_to "Ištrinti komentarą", [comment.article, comment], data: {
turbo_method: :delete,
turbo_confirm: "Ar tikrai?"
} %>
</p>
<% end %>
Paspaudus šią naują "Ištrinti komentarą" nuorodą, bus išsiųstas DELETE /articles/:article_id/comments/:id
užklausa į CommentsController
, kuris galės rasti komentarą, kurį norime ištrinti. Taigi, pridėkime destroy
veiksmą į mūsų kontrolerį (app/controllers/comments_controller.rb
):
class CommentsController < ApplicationController
def create
@article = Article.find(params[:article_id])
@comment = @article.comments.create(comment_params)
redirect_to article_path(@article)
end
def destroy
@article = Article.find(params[:article_id])
@comment = @article.comments.find(params[:id])
@comment.destroy
redirect_to article_path(@article), status: :see_other
end
private
def comment_params
params.require(:comment).permit(:commenter, :body, :status)
end
end
destroy
veiksmas ras straipsnį, kurį žiūrime, rasi komentarą @article.comments
kolekcijoje ir jį pašalins iš duomenų bazės, o tada nukreips mus į straipsnio rodinio veiksmą.
10.1 Susijusių objektų trynimas
Jei ištrinsite straipsnį, taip pat reikės ištrinti susijusius komentarus, kitaip jie tiesiog užims vietą duomenų bazėje. „Rails“ leidžia naudoti asociacijos dependent
parinktį, kad tai pasiektumėte. Pakeiskite Article
modelį, app/models/article.rb
, kaip parodyta žemiau:
class Article < ApplicationRecord
include Visible
has_many :comments, dependent: :destroy
validates :title, presence: true
validates :body, presence: true, length: { minimum: 10 }
end
11 Saugumas
11.1 Pagrindinė autentifikacija
Jei savo tinklaraštį paskelbtumėte internete, bet kas galėtų pridėti, redaguoti ir ištrinti straipsnius arba ištrinti komentarus.
„Rails“ teikia HTTP autentifikacijos sistemą, kuri puikiai veiks šioje situacijoje.
ArticlesController
mums reikia būdo blokuoti prieigą prie įvairių veiksmų, jei asmuo nėra autentifikuotas. Čia galime naudoti „Rails“ http_basic_authenticate_with
metodą, kuris leidžia prieigą prie reikiamo veiksmo, jei tas metodas tai leidžia.
Norėdami naudoti autentifikacijos sistemą, ją nurodome mūsų ArticlesController
viršuje, app/controllers/articles_controller.rb
. Mūsų atveju norime, kad vartotojas būtų autentifikuotas kiekviename veiksme, išskyrus index
ir show
, todėl parašome taip:
class ArticlesController < ApplicationController
http_basic_authenticate_with name: "dhh", password: "secret", except: [:index, :show]
def index
@articles = Article.all
end
# snippet for brevity
Taip pat norime leisti tik autentifikuotiems vartotojams ištrinti komentarus, todėl CommentsController
(app/controllers/comments_controller.rb
) parašome:
class CommentsController < ApplicationController
http_basic_authenticate_with name: "dhh", password: "secret", only: :destroy
def create
@article = Article.find(params[:article_id])
# ...
end
# snippet for brevity
Dabar, jei bandysite sukurti naują straipsnį, jums bus pateiktas pagrindinės HTTP autentifikacijos iššūkis:
Įvedus teisingą naudotojo vardą ir slaptažodį, jūs liksite autentifikuotas, kol bus reikalaujamas kitas naudotojo vardas ir slaptažodis arba naršyklė bus uždaryta. Kiti autentifikavimo metodai yra prieinami "Rails" programoms. Dvi populiarios autentifikavimo papildymo "Rails" yra Devise ir Authlogic gem, kartu su kitais.
11.2 Kiti saugumo apsvarstymai
Saugumas, ypač interneto programose, yra plačiai ir išsamiai nagrinėjama sritis. "Rails" programos saugumas yra išsamiau aptartas Ruby on Rails saugumo vadove.
12 Kas toliau?
Dabar, kai matėte savo pirmąją "Rails" programą, galite ją atnaujinti ir eksperimentuoti savarankiškai.
Atminkite, kad jums nereikia visko daryti be pagalbos. Jei jums reikia pagalbos pradėti dirbti su "Rails", drąsiai kreipkitės į šiuos pagalbos šaltinius:
13 Konfigūracijos klaidos
Paprastiausias būdas dirbti su "Rails" yra saugoti visus išorinius duomenis kaip UTF-8. Jei to nedarote, "Ruby" bibliotekos ir "Rails" dažnai gali konvertuoti jūsų natyvius duomenis į UTF-8, tačiau tai ne visada veikia patikimai, todėl geriau užtikrinti, kad visi išoriniai duomenys būtų UTF-8.
Jei šioje srityje padarėte klaidą, dažniausias simptomas yra juodas deimantas su klausimo ženklu viduje, atsirandantis naršyklėje. Kitas dažnas simptomas yra simboliai, tokie kaip "ü", atsirandantys vietoj "ü". "Rails" ėmėsi keleto vidinių veiksmų, kad būtų sumažintos šių problemų dažniausios priežastys, kurias galima automatiškai aptikti ir ištaisyti. Tačiau, jei turite išorinių duomenų, kurie nėra saugomi kaip UTF-8, tai kartais gali sukelti šių problemų, kurias "Rails" negali automatiškai aptikti ir ištaisyti.
Dvi labai dažnos duomenų, kurie nėra UTF-8, šaltiniai:
- Jūsų teksto redaktorius: Dauguma teksto redaktorių (pvz., TextMate) pagal nutylėjimą išsaugo failus kaip UTF-8. Jei jūsų teksto redaktorius to nedaro, tai gali lemti specialių simbolių, kuriuos įvedate į savo šablonus (pvz., é), atsiradimą naršyklėje kaip deimantas su klausimo ženklu viduje. Tai taip pat taikoma jūsų i18n vertimo failams. Dauguma redaktorių, kurie jau nenumato UTF-8 kaip numatytąjį (pvz., kai kurios "Dreamweaver" versijos), siūlo būdą pakeisti numatytąjį į UTF-8. Padarykite tai.
- Jūsų duomenų bazė: "Rails" pagal nutylėjimą konvertuoja duomenis iš jūsų duomenų bazės į UTF-8 ribose. Tačiau, jei jūsų duomenų bazė viduje nenaudoja UTF-8, ji gali nepavykti saugoti visus simbolius, kuriuos įveda jūsų vartotojai. Pavyzdžiui, jei jūsų duomenų bazė viduje naudoja "Latin-1", o jūsų vartotojas įveda rusų, hebrajų ar japonų simbolį, duomenys bus visam laikui prarasti, kai jie patenka į duomenų bazę. Jei įmanoma, naudokite UTF-8 kaip vidinį duomenų bazės saugojimo formatą.
Atsiliepimai
Jūs esate skatinami padėti pagerinti šio vadovo kokybę.
Prašome prisidėti, jei pastebite rašybos klaidų ar faktinių klaidų. Norėdami pradėti, galite perskaityti mūsų dokumentacijos prisidėjimo skyrių.
Taip pat gali būti nepilnos informacijos arba informacijos, kuri nėra atnaujinta. Prašome pridėti bet kokią trūkstamą dokumentaciją pagrindiniam. Patikrinkite Edge vadovus pirmiausia, ar problemas jau išspręsta arba ne pagrindinėje šakoje. Patikrinkite Ruby on Rails vadovų gaires dėl stiliaus ir konvencijų.
Jei dėl kokios nors priežasties pastebite kažką, ką reikia ištaisyti, bet negalite patys tai pataisyti, prašome pranešti apie problemą.
Ir galiausiai, bet ne mažiau svarbu, bet koks diskusijos dėl Ruby on Rails dokumentacijos yra labai laukiamos oficialiame Ruby on Rails forume.