አሁን አዲስ ተጠቃሚዎች ለጣቢያችን መመዝገብ የሚችሉ ከሆነ (ምዕራፍ 7)፣ የተመዘገቡ ተጠቃሚዎችን ወደ ጣቢያችን የመግባት እና የመውጣት ችሎታ የመስጠቱ ጊዜ አሁን ነው ማለት ነው፡፡ በዚህ ምዕራፍ ውስጥ፣ አንድ መሰረታዊ ነገር ግን ሙሉ በሙሉ ተግባራዊ የሆነ የመግቢያ ስርዓትን እንተገብራለን፤ አሳሹ በተጠቃሚው እስኪዘጋ ድረስ አፕልኬሽኑ የግባት ሁኔታውን ያቆያል። ከትግባሬው የሚገኘው የማረጋገጫ ስርዓት፣ ጣቢያውን ለማበጀት እና በአሁንተጠቃሚው የግብዓት ሁኔታ እና ማንነት ላይ የተመሰረተ አንድ የፈቃድ ቅርጸትን ተግባራዊ ለማድረግ ያስችለናል፡፡ ለምሳሌ፣ በግብዓት/በውጣት አገናኞች እና በአንድ የመገለጫ አገናኝ የጣቢያውን ራስጌ ማዘመን እንችላለን፡፡
በምዕራፍ 10 ውስጥ፣ የገቡ ተጠቃሚዎች ብቻ የተጠቃሚ ማውጫ ገጽን እንዲጎበኙ፣ ትክክለኛው ተጠቃሚ ብቻ የራሱን መረጃ ለማረም ገጹን እንዲደርስ፣ አስተዳዳሪ ተጠቃሚዎች ብቻ ውሂበጎታው ላይ የሚገኙ ሌሎች ተጠቃሚዎችን እንዲሰርዙ የሚያስገድድ አንድ የጥበቃ ቅርጸትን ተግባር ላይ እናውላለን፡፡ በመጨረሻም በምዕራፍ 13 ላይ አንድ የግቡ ተጠቃሚ ማንነትን በመጠቀም፣ ከዚሁ ተጠቃሚ ጋር የተዛመዱ አጪርጽሑፎችን እንፈጥራለን፡፡ በምዕራፍ 14 ላይ ደግሞ የአሁንተጠቃሚውን የዚህን አፕልኬሽን ተጠቃሚዎች እንዲከተል እንፈቅዳለን (ስለዚህም አንድ የአጪርጽሑፎች ቀላቢን ይቀበላል፡፡)
በዚህ ምዕራፍ ውስጥ የሚሰራው የማረጋገጫ ስርዓት፣ በምዕራፍ 9 ላይ ለሚበለጽገው የላቀ የመግቢያ ስርዓት ልክ እንደ አንድ መሰረት ሆኖ ያገለግላል፡፡ አሳሹ በሚዘጋበት ጊዜ ተጠቃሚዎችን “ከመርሳት” ይልቅ፣ ምዕራፍ 9 ተጠቃሚዎችን በራስሰር መዘከርን ይጀምራል፣ እና ከዚያ በአንድ “ዘክረኝ” ማመልከቻሳጥን ዋጋ ላይ በመመርኮዝ ተጠቃሚዎችን በምርጫ ይዘክራል። በዚህ ምክንያትም፣ በምዕራፍ 8 እና በምዕራፍ 9 ውስጥ የበለጸጉት ተግባራት ሁሉ በአንድ ላይ ተጣምረው፣ በድር አራሰራር ላይ እጅግ የተለመዱትን ሶስቱን የመግቢያ ስርዓቶች ያበለጽጋሉ ማለት ነው፡፡
ሃ.ጽ.ማ.ስ ከቀደሙት መጠይቆች ማንኛውንም መረጃ መጠቀም የማይችል፣ እያንዳንዱን መጠይቅ ልክ እንደ አንድ ገለልተኛ ልውውጥ አድርጎ የሚቆጥር ሁኔታ አልባ ስምምነት ነው። ይህ ማለት፣ ተጠቃሚ ከአንዱ ገጽ ወደ አንዱ ገጽ በሚቀያይርበት ወቅት በሃይለ ጽሑፍ ማዘዋወሪያ ስምምነት በኩል የአንድ ተጠቃሚ ማንነትን የማስታወስ መንገድ የለም ማለት ነው፤ ስለሆነም የተጠቃሚ መግቢያ የሚያስፈልጋቸው የድር አፕልኬሽኖች አንድ ክፍለጊዜን መጠቀም ይኖርባቸዋል፤ ይህ ክፍለጊዜን የመጠቀም ዘዴ በሁለት ኮምፒዩተሮች መካከል አንድ ጊዜያዊ የሆነ ግንኙነትን ይፈጥራል (አንድ የድር አሳሽን የሚያስኬድ አንድ መደበኛ ኮምፒዩተርን፣ ከአንድ ሬይልስን የሚያስኬድ አገልጋይ ጋር መገናኘት እንደማለት ነው)።
በሬይልስ ውስጥ ክፍለጊዜወችን ለመተግበር በጣም የተለመደው ብልሃት፣ በተጠቃሚው አሳሽ ውስጥ መጠኑ አነስተኛ የሆነ ጽሑፍን የያዙ ብስኩቶችን ማስቀመጥን ያሳትፋል፡፡ ብስኩቶች ከአንዱ ገጽ ወደ ሚቀጥለው ገጽ ስለሚቆዩ እና መረጃዎችን ማከማቸት ስለሚችሉ (ለምሳሌ የተጠቃሚ-መታወቂያን)፤ በአፕልኬሽኑ የገባ ተጠቃሚን ከውሂበጎታ ፈልጎ የማግኘት ጥቅም ላይ ሊውሉ ይችላሉ፡፡ በዚህ ክፍል ውስጥ እና በክፍል 8.2 ውስጥ አሳሹ በሚዘጋብት1 ወቅት በራስሰር ጊዜያቸው የሚቃጠል ጊዜያዊ ክፍለጊዜወችን ለመስራት ክፍለጊዜ (session
) የተባለውን የሬይልስ ዘዴን እንጠቀማለን፡፡ በቅርቡ በምዕራፍ 9 ላይ ከክፍለጊዜ ዘዴ ጋር የተዛመዱ የ‘ብስኩቶች (cookies
) ዘዴወችን በመጠቀም ለረዥም ጊዜ መኖር የሚችሉ ክፍለጊዜወችን እንዴት መስራት እንደሚቻል እንማራለን።
ክፍለጊዜወችን ልክ እንደ አንድ ሙሉው.ሁ.ማ ሃብት አድርጎ መቅረጽ አስፈላጊ ነው፤ የመግቢያ ገጹን መጎብኘቱ ለአዲስ (new) ክፍለጊዜዎች አንድ ቅጽን ያቀርባል፣ ግብዓት አንድ ክፍለጊዜን ይፈጥራል (Create) ውጣት ደግሞ የተፈጠረውን ክፍለጊዜ ያጠፋል (Destroy)። የተጠቃሚ ሃብቱ ውሂብን ቋሚ አድርጎ ለማኖር አንድ የውሂበጎታ ደጀንን (በተጠቃሚ ቅርጸቱ በኩል) እንደተጠቀመው ሁሉ፣ የክፍለጊዜወች ሃብት ደግሞ ውሂብን ቋሚ አድርጎ ለማኖር ብስኩቶችን ይጠቀማሉ፤ በዚህ ምክንያትም አብዛኛው የግብዓት ስራ፣ በብስኩት ላይ የተመሰረተ የማረጋገጫ ፋብሪካን መገንባትን በማሳተፍ የመጣ ይሆናል፡፡ በዚህ ክፍል እና በሚቀጥለው ክፍል ላይ፣ አንድ የክፍለጊዜወች መቆጣጠሪያን፣ አንድ የግብዓት ቅጽን እና አስፈላጊ የሆኑ የመቆጣጠሪያ ተግባሮችን ለመስራት ዝግጅት እናደርጋለን፡፡ ከዚያ አስፈላጊውን የክፍለጊዜ አንቀሳቃሽ ኮድን በማከል የተጠቃሚ ግብዓትን በክፍል 8.2 ላይ እናጠናቅቃለን።
ከዚህ በፊት እንዳለፉት ምዕራፎች ሁሉ፣ ስራችንን በአንድ የርእስ ቅርንጫፍ ላይ እናካሂድ እና መጨረሻ ላይ ያደረግናቸውን ለውጦች ወደ ዋና ቅርንጫፉ እናዋህዳቸዋለን፡-
$ git checkout -b መሰረታዊ-መግቢያ
የግብዓት እና የመውጣት አካላት፣ ከተወሰኑ የክፍለጊዜወች መቆጣጠሪያ የው.ሁ.ማ ተግባሮች ጋር ይዛመዳሉ፤ የግብዓት ቅጹ በ‘አዲስ (new
) ተግባር ይስተናገዳል (በዚህ ክፍል ላይ ይሸፈናል)፤ በርግጥ የግብዓት ቅጽ የሚስተናገደው አንድ የ‘ዓስቀምጥ (POST)
መልእክትን ወደ ፍጠር (create
) ተግባር በመላክ ሲሆን (ክፍል 8.2)፤ የውጣት ቅጹ ደግሞ አንድ የሠርዝ (DELETE)
መልእክትን ወደ አጥፋ (destroy
) ተግባር በመላክ ይስተናገዳል (ክፍል 8.3)፡፡ (እነዚህ ተግባሮች ሰንጠረዥ 7.1 ላይ የተመለከቱትን የሃ.ጽ.ማ.ስ ግሶች ከሬይልስ ተግባሮች ጋር ያላቸውን ጥምረት እንደሚያሳይ ልታስተውሉ ይገባል።)
ስራችንን ለመጀመር፣ አንድ የክፍለጊዜ መቆጣጠሪያን ከአንድ አዲስ (new
) ተግባር ጋር እናመነጫለን (ዝርዝር 8.1)።
$ rails generate controller Sessions new
(የ‘አዲስ (new
) ተግባርን ማካተቱ ትይታዎችንም ያመነጪልናል፣ ለዚህም ነው እዚህ ላይ ከትይታዎች ጋር የማይዛመዱትን የ‘ፍጠር (create
) እና የ‘አጥፋ (destroy
) ተግባሮችን ያላካተትነው፡፡) እቅዳችን በክፍል 7.2 ላይ ያደረግነውን የምዝገባ ገጽ ቅድን በመከተል፣ በምስል 8.1 ስእላዊ መግለጫ ላይ እንደሚታየው፣ አዲስ ክፍለጊዜወችን ለመፍጠር አንድ የግብዓት ቅጽን መፍጠር ነው፡፡
የተጠቃሚዎች ሃብት ልዩ የሆነ የ‘ሃብቶች (resources
) ዘዴን ተጠቅሞ ሁሉንም የሙሉው.ሁ.ማ ማዘዋወሪያ ስብስቦችን በራስሰር ፈጥሮ ነበረ (ዝርዝር 7.3)፤ ይሁን እንጅ የክፍለጊዜወች ሃብት ሶስት የተሰየሙ ማዘዋወሪያወች ብቻ ይኖሩታል፤ እነሱም በ‘ግባ (gba
) ማዘዋወሪያ የሚስተናገዱ (የ‘ዓግኝ (GET)
) እና የ‘ዓስቀምጥ (POST)
መጠይቆች፤ እና በ‘ውጣ (wta
) ማዘዋወሪያ የሚስተናገድ የ‘ሠርዝ (DELETE)
መጠይቅ ናቸው። ውጤቱ በዝርዝር 8.2 ውስጥ ይታያል (በ‘ሬይልስ መቆጣጠርያ አመንጪ (rails generate controller
) ትእዛዝ የመነጩ አላስፈላጊ የሆኑ ማዘዋወሪያወችንም ይሰርዛል)፡፡
config/routes.rb
Rails.application.routes.draw do
root 'quami_getss#menesha'
get '/erdata', to: 'quami_getss#erdata'
get '/silegna', to: 'quami_getss#silegna'
get '/agignun', to: 'quami_getss#agignun'
get '/temezgeb', to: 'teteqamis#new'
get '/gba', to: 'sessions#new'
post '/gba', to: 'sessions#create'
delete '/wta', to: 'sessions#destroy'
resources :teteqamis
end
በዝርዝር 8.2 ውስጥ የሚገኙትን ማዘዋወሪያወች በዝርዝር 8.3 ላይ እንደሚታየው፣ ዝርዝር 8.1 ላይ የክፍለጊዜ መቆጣጠሪያ ስናመነጪ አብሮ የመነጨው የክፍለጊዜ ፈተና ላይ አንድ አዲስ የግብዓት ማዘዋወሪያ በማከል እናዘምነዋለን።
test/controllers/sessions_controller_test.rb
require 'test_helper'
class SessionsControllerTest < ActionDispatch::IntegrationTest
test "አዲስ ማግኘት አለበት" do
get gba_path
assert_response :success
end
end
በሰንጠረዥ 8.1 ላይ እንደሚታየው፣ በዝርዝር 8.2 ውስጥ የተበየኑት ማዘዋወሪያወች ልክ እንደ ተጠቃሚዎች ዓ.አ.ሃ.አወች እና ተግባሮች (ሰንጠረዥ 7.1) ከዓ.አ.ሃ.አወቹ እና ከተግባሮቹ ጋር ይዛመዳሉ።
ሃ.ጽ.ማ.ስ መጠይቅ | ዓ.አ.ሃ.አ | ስዩም ማዘዋወሪያ | ተግባር | ጥቅም |
GET |
/gba | gba_path |
new |
ለአንድ አዲስ ክፍለጊዜ አንድ ገጽን ማቅረብ (ግብዓት) |
POST |
/gba | gba_path |
create |
አንድ አዲስ ክፍለጊዜን መፍጠር (ግብዓት) |
DELETE |
/wta | wta_path |
destroy |
አንድ ክፍለጊዜን መሰረዝ (ውጣት) |
አሁን ብዙ የተበጁ ስዩም ማዘዋወሪያወችን በአፕልኬሽናችን ላይ ስለጨመርን፣ የ‘ሬይልስ-ማዘዋወሪያዎች (rails routes
) ትእዛዝን በመጠቀም የምናገኘውን የተሟላ የአፕልኬሽናችንን የማዘዋወሪያወች ዝርዝር መመልከቱ ጠቃሚ ነው:-
$ rails routes
Prefix Verb URI Pattern Controller#Action
root GET / quami_getss#menesha
erdata GET /erdata(.:format) quami_getss#erdata
silegna GET /silegna(.:format) quami_getss#silegna
agignun GET /agignun(.:format) quami_getss#agignun
temezgeb GET /temezgeb(.:format) teteqamis#new
gba GET /gba(.:format) sessions#new
POST /gba(.:format) sessions#create
wta DELETE /wta(.:format) sessions#destroy
teteqamis GET /teteqamis(.:format) teteqamis#index
POST /teteqamis(.:format) teteqamis#create
new_teteqami GET /teteqamis/new(.:format) teteqamis#new
edit_teteqami GET /teteqamis/:id/edit(.:format) teteqamis#edit
teteqami GET /teteqamis/:id(.:format) teteqamis#show
PATCH /teteqamis/:id(.:format) teteqamis#update
PUT /teteqamis/:id(.:format) teteqamis#update
DELETE /teteqamis/:id(.:format) teteqamis#destroy
ውጤቱን በዝርዝር ለመረዳት መሞከሩ ይሄን ያህል አስፈላጊ አይደለም፤ ነገር ግን በዚህ መንገድ ያሉትን ማዘዋወሪያወች መመልከቱ በአፕልኬሽናችን የሚደገፉ ተግባሮችን ለመመልከት አንድ አጠቃላይ የሆነ ርዴትን ይሰጠናል።
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
GET gba_path
) እና በ‘ዓስቀምጥ ግባ_መንገድ (POST gba_path
) መካከል ያለው ልዩነት ምንድን ነው?
rails routes
) ውጤትን ፈልግ (grep
) ወደተባለው ትእዛዝ በቱቦ በማሳለፍ (Piping)፣ ከተጠቃሚው ሃብት ጋር የሚዛመዱትን ማዘዋወሪያወች በሙሉ ዘርዝሩ። እያንዳንዱ ሃብት ስንት ማዘዋወሪያወች አሉት? ጠቃሚ ምክር:- የዚህን መልስ በቀላሉ ለማግኘት በማዘዥያ መስመር ላይ መሰረታዊ እውቀትን ለማግኘት የሚያስፈልገውን ትምህርት ተማርውስጥ ስለ ግሬፕ (grep) የሚያስተምረውን ክፍል ተመልከቱ፡፡
አስፈላጊ የሆነውን መቆጣጠሪያ እና ማዘዋወሪያ ከበየንን በኋላ፤ አሁን የአዲስ ክፍለጊዜ ማለትም የግብዓት ቅጽ ትይታን እንሞላለን፡፡ በምስል 8.1 ላይ የተመለከውን ስእላዊ መግለጫ ምስል 7.12 ላይ ከተመለከተው ስእላዊ መግለጫ ጋር ብናነጻጽር፣ የምዝገባ ቅጹ አራት መስኮች ሲኖሩት የግብዓት ቅጹ ግን ሁለት (የኤመልእክት እና የመሕለፈቃል) መስኮችን ከመያዙ በስተቀር የግብዓት ቅጹ ከምዝገባ ቅጹ ጋር ተመሳሳይ እንደሆነ እንገነዘባለን።
በምስል 8.2 ላይ እንደሚታየው፣ የግብዓት መረጃው ብቁ ካልሆነ የግብዓት ገጹን መልሰን ማቅረብ አና አንድ የስህተት መልእክትን ማሳየት እንፈልጋለን። በክፍል 7.3.3 ውስጥ የስህተት መልእክቶችን ለማሳየት አንድ የስህተት መልእክቶች ከፊልን ተጠቅመን ነበር፤ እነዛ የስህተት መልእክቶችም በ‘ንቅ መዝገብ ተዘጋጅተው በራስሰር እንደሚቀርቡም ተመልክተን ነበር። ይህ ክፍለጊዜ ግን የ‘ንቅ መዝገብ ቁስ ስላልሆነ እና ክፍለጊዜውን በመፍጠር ላይ የሚከሰቱ ስህተቶች ላይ ስለማይሰራ፣ ስህተቱን ልክ እንደ አንድ የብልጪታ መልእክት አድርገን እናቀርበዋለን።
የምዝገባ ቅጹ የ‘ቅጽ_ጋር (form_with
) ረጅው የ‘@ተጠቃሚ (@teteqami
) ቅርፀ ተለዋዋጩን ልክ እንደ አንድ ነጋሪአሴት አድርጎ እንደሚወስድ ዝርዝር 7.15 ላይ አይተን ነበር:-
<%= form_with(model: @teteqami, local: true) do |ቅ| %>
.
.
.
<% end %>
በክፍለጊዜ እና በምዝገባ ቅጽ መካከል ያለው ዋነኛው ልዩነት የክፍለጊዜ ቅርጸት ያለመኖሩ ነው፡፡ ስለሆነም ከ‘@ተጠቃሚ (@teteqami
) ቅርፀ ተለዋዋጪ ጋር የሚዛመድ ዋጋ የለም ማለት ነው፡፡ ስለዚህ አዲሱን የክፍለጊዜ ቅጽ በምንገነባበት ጊዜ ለ‘ቅጽ_ጋር (form_with
) በመጠኑ የተለየ መረጃ መስጠት ይኖርብናል። እዚህ ላይ:-
form_with(model: @teteqami, local: true)
ሬይልስን የቅጹን ተግባር (action
) ወደ /ተጠቃሚዎች (/teteqamis) ዓ.አ.ሃ.አ ማስቀመጥ (POST)
እንደሚኖርበት ከሁኔታው እንዲያውቅ ያስችለዋል፣ ክፍለጊዜዎችን በተመለከተ ግን ሁኔታው የተለየ ነው፤ ክፍለጊዜወች የ‘ንቅ መዝገብ ቁስ አባል ስላልሆነ ከሱ ጋር የሚዛመደውን ዓ.አ.ሃ.አ ከክልሉ (Scope) ጋር ማመላከት ይኖርብናል:-
form_with(url: gba_path, scope: :session, local: true)
አሁን ተገቢውን ቅጽ_ጋር (form_with
) በእጃችን አስገብተን፣ በዝርዝር 7.15 ውስጥ ያለውን የምዝገባ ቅጽን ልክ እንደ አንድ ቅድ አድርጎ በመውሰድ፣ ከምስል 8.1 ስእላዊ መግለጫ ጋር የሚመሳሰል አንድ ግብዓተ ቅጽን መስራቱ ቀላል ይሆናል። የመጨረሻው የቅጹ ውጤት በዝርዝር 8.4 ውስጥ እንደሚታየው ይሆናል፡፡
app/views/sessions/new.html.erb
<% provide(:title, "ይግቡ") %>
<h1>ይግቡ</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_with(url: gba_path, scope: :session, local: true) do |ቅ| %>
<%= ቅ.label :emelekt, 'ኤመልእክት' %>
<%= ቅ.email_field :emelekt, class: 'form-control' %>
<%= ቅ.label :password, 'መሕለፈቃል' %>
<%= ቅ.password_field :password, class: 'form-control' %>
<%= ቅ.submit "ግባ", class: "btn btn-primary" %>
<% end %>
<p>አዲስ ተጠቃሚ? <%= link_to "ይመዝገቡ", temezgeb_path %></p>
</div>
</div>
ለምቾት ሲባል በምዝገባ ገጹ ላይ አንድ አገናኝን እንዳከልን ልብበሉ። በዝርዝር 8.4 ውስጥ በሚገኘው ኮድ የተፈጠረው የምዝገባ ቅጽ በምስል 8.3 ላይ ይታያል። (የ “ይግቡ” መዳሰሻ አገናኙ ገና ስላልተሟላ፣ የግብዓት ቅጹን ለማግኘት /ግባ (/gba) ዓ.አ.ሃ.አን በአድራሻ አሞሌው ላይ በቀጥታ መጻፍ ይኖርባችኋል፡፡ በክፍል 8.2.3 ውስጥ ይህንን እንከን እንከነ ቢስ እናደርገዋለን፡፡)
በቅጹ የመነጨው የሃ.ጽ.መ.ቋ ኮድ በዝርዝር 8.5 ላይ ቁልጪ ብሎ ይታያል፡፡
<form accept-charset="UTF-8" action="/gba" method="post">
<input name="authenticity_token" type="hidden"
value="NNb6+J/j46LcrgYUC60wQ2titMuJQ5lLqyAbnbAUkdo=" />
<label for="session_emelekt">ኤመልእክት</label>
<input class="form-control" id="session_emelekt"
name="session[emelekt]" type="email" />
<label for="session_password">መሕለፈቃል</label>
<input id="session_password" name="session[password]"
type="password" />
<input class="btn btn-primary" name="commit" type="submit"
value="ግባ" />
</form>
ዝርዝር 8.5 ውስጥ ያለውን ኮድ ዝርዝር 7.17 ካለው ኮድ ጋር በማነጻጸር፣ ይህንን ቅጽ ማስረከቡ የ‘ሰሚአሴቶች (params
) ተርታው ከኤመልእክት መስኩ ጋር የሚዛመድ አንድ የ params[:session][:emelekt]
ተርታ እና ከመሕለፈቃል መስኩ ጋር የሚዛመድ አንድ የ params[:session][:password]
ተርታ ውጤትን እንደሚያስገኝ መገመት ትችሉ ይሆናል፡፡
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
በለፈው ክፍለ ጊዜ ተጠቃሚዎችን ለመፍጠር (ለመመዝገብ) የመጀመሪያው ቅድመ ሁኔታ ብቁ ያልሆኑ የቅጽ መረጃ ግብዓቶችን በወጉ ማስተናገድ ነበር። አሁንም ለክፍለጊዜወች ፈጠራ (ግብዓት) ያንኑ ማለት ብቁ ያልሆኑ የቅጽ መረጃ ግብዓቶችን ጥጋቸውን በማስያዝ እንጀምራለን፡፡ አንድ ቅጽ በሚረከብበት ጊዜ ምን እንደሚከሰት በመገምገም እንጀምር እና ከዚያ በግብዓት ጊዜ የሚከሰቱትን አለመሳካቶች ቅጹ ላይ ጠቃሚ የሆነ መረጃ ለተጠቃሚው ለማሳየት፣ (ልክ ምስል 8.2 ላይ እንደሚታየው ስእላዊ መግለጫ) አጋዥ የሆኑ የስህተት መልእክቶችን እናዘጋጃለን፤ ከዚያ በኤመልእክት/የመሕለፈቃል ጥምረት ብቃት ላይ በመመርኮዝ የእያንዳንዱን የግባት ርካቤ በመገምገም፣ ለስኩ ግብዓት መሰረት እናስቀጣለን (ክፍል 8.2)።
ለክፍለጊዜወች መቆጣጠሪያ የ‘ፍጠር (create
) እና የ‘አጥፋ (destroy
) ተግባሮችን ከ‘አዲስ (new
) ተግባር ጋር በመበየን እንጀምራለን (ዝርዝር 8.6)፡፡ በዝርዝር 8.6 ውስጥ ያለው የ‘ፍጠር (create
) ተግባር አዲስ (new
) ትይታ ከማቅረብ በቀር ሌላ ምንም ነገር አያደርግም፤ ይሁን እንጅ እኛን ለማስጀመር ግን በቂ ነው፡፡ የ/ክፍለጊዜወች/አዲስ (/sessions/new) ቅጽን ማስረከቡ በምስል 8.4 እና በምስል 8.5 ላይ የሚታዩትን ውጤቶች ይሰጣል፡፡
create
) ተግባር በኩር ስሪት። app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
def new
end
def create
render 'new'
end
def destroy
end
end
በምስል 8.5 ውስጥ፣ የአርምን መረጃ በትንቃቄ ስንመረምር በክፍል 8.1.2 መጨረሻ ላይ እንደተገለጸው፣ የርክቡ ውጤት በ‘ክፍለጊዜ‘ው (session
) ቁልፍ ውስጥ የኤመልእክትን እና መሕለፈቃልን የያዘ አንድ የ‘ሰሚአሴቶች (params
) ተርታን እንደሚያስገኝ መግንዘብ እንችላለን። ይህም (ከሬይልስ ሰሌዳ የወጡ አላስፈላጊ ዝርዝሮችን በመተው) ልክ እንደሚከተለው ሁኖ ይታያል:-
---
session:
email: 'teteqami@misalei.com'
password: 'foobar'
commit: ግባ
action: create
controller: sessions
ልክ እንደ ተጠቃሚ ምዝገባ (ምስል 7.16) እነዚህ ሰሚአሴቶች በዝርዝር 4.13 ውስጥ እንዳየነው፣ አንድ እቅፍቅፍ ተርታን ይመሰርታሉ፡፡ በተለየ ሁኔታ ሰሚአሴቶች (params
) ይህን የመሰለ ገጽታ ያለው አንድ የእቅፍቅፍ ተርታን ይይዛል:-
{ session: { password: "foobar", emelekt: "teteqami@misalei.com" } }
‘ምን የመሰለ አንድ እቅፍቅፍ ተርታን ይይዛል። ይህ ማለትም:-
params[:session]
ራሱ አንድ ተርታ ነው፤ ማለት ነው፤ ስለዚህ:-
{ password: "foobar", emelekt: "teteqami@misalei.com" }
የተረከበው የኤመልእክት አድራሻ ሲሆን:-
params[:session][:emelekt]
የተረከበው መለያ ይሆናል ማለት ነው:-
params[:session][:password]
በሌላ አነጋገር በ‘ፍጠር (create
) ተግባር ውስጥ፣ የ‘ሰሚአሴቶች (params
) ተርታው ተጠቃሚዎችን በኤመልእክት እና በመሕለፈቃል ለማረጋገጥ የሚስፈገው መረጃ በሙሉ አለው ማለት ነው፡፡
በአጋጣሚ አይደለም፣ እኛ በትክክል የምንፈልጋቸው ሁለት ዘዴዎች አሉን፣ እነሱም በ‘ንቅ መዝገብ የተሰጠ የ‘ተጠቃሚ.ፈልግበ (Teteqami.find_by
) ዘዴ (ክፍል 6.1.4) እና በ‘ጥብቅ_መሕለፈቃል_አለው (has_secure_password
) የተሰጠ የ‘አረጋግጥ (authenticate
) ዘዴ (ክፍል 6.3.4) ናቸው። አንድ ብቃት ለሌለው ማረጋገጫ (ክፍል 6.3.4) የ‘አረጋግጥ (authenticate
) ዘዴ ሃሰት‘ን (false
) እንደሚመልስ እናውቃለን፣ እናም የተጠቃሚ ግብዓት አሰራርን ተግባራዊ ለማድረግ፣ ያለን ስልት በዝርዝር 8.7 እንደተመለከተው ሊጠቃለል ይችላል፡፡
app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
def new
end
def create
teteqami = Teteqami.find_by(emelekt: params[:session][:emelekt].downcase)
if teteqami && teteqami.authenticate(params[:session][:password])
# ተጠቃሚውን አስገባ እና ወደ ተጠቃሚው ማሳያ ገጽ አዘዋውር፡፡
else
# አንድ የስህተት መልእክት ፍጠር።
render 'new'
end
end
def destroy
end
end
በዝርዝር 8.7 ውስጥ በጉልህ ቀለም የተቀባው የመጀመሪያው መስመር፣ የተረከበውን የኤመልእክት አድራሻ በመጠቀም ተጠቃሚውን ከውሂበጎታው ጎትቶ ያወጣል፡፡ (በክፍል 6.2.5 ትምህርታችን ላይ ሁሉም የኤመልእክት አድራሻዎች በንዑስ-ፊደል እንደሚቀመጡ አስታውሱ፤ ስለዚህ የተረከበው የኤመልእክት አድራሻ ብቁ በሚሆንበት ጊዜ ተዛማጅነቱን ለማረጋገጥ እዚህ ላይ የ‘ንዑስ-ፊደል (downcase
) ዘዴን እንጠቀማለን፡፡) የሚቀጥለው መስመር ትንሽ ግራ ሊያጋባ ይችል ይሆናል፣ ነገር ግን በሬይልስ ፕሮግራም አሰራር ውስጥ በጣም የተለመደ ስነአጻጻፍ ነው:-
teteqami && teteqami.authenticate(params[:session][:password])
ይህ በውጤቱ የተገኘው ተጠቃሚ ብቁ እንደሆነ እና እንዳልሆነ ለማወቅ የ‘እና (&&
) ማነጻጸርያን ይጠቀማል (ምክንያታዊ እና (logical and) በመባልም ይታወቃል)፡፡ ከ‘ምንም (nil
) እና ከ‘ሃሰት (false
) ውጪ የሆነ ማንኛውም ቁስ በአንድ ቡሌያን አውድ (ክፍል 4.2.2) ውስጥ እውነት (true
) መሆኑን ከግምት ውስጥ በማስገባት ይሰራል፣ በሰንጠረዥ 8.2 ውስጥ ሊያጋጥሙ የሚችሉ ክስተቶች በአጪሩ ተዘርዝራዋል፡፡ ከሰንጠረዥ 8.2 እንደምናየው የ‘ከሆነ (if
) ዓረፍተሐሳቡ እውነት (true
) የሚሆነው፣ አንድ ተጠቃሚ ከቀረበ ኤመልእክት ጋር በውሂበጎታው ውስጥ ሲኖር እና አንድ የቀረበ መሕለፈቃል ካለ ብቻ ነው፡፡
ተጠቃሚ | መሕለፈቃል | ሀ && ለ |
የሌለ | ማንኛውምነገር | (nil && [ማንኛውምነገር]) == false |
ብቁ ተጠቃሚ | የተሳሳተ መሕለፈቃል | (true && false) == false |
ብቁ ተጠቃሚ | ትክክለኛ መሕለፈቃል | (true && true) == true |
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
teteqami = nil
እና teteqami = Teteqami.first
በማድረግ ጀምሩ። ጠቃሚ ምክር:- የዚህን መልስ በቀላሉ ለማግኘት፣ ውጤቱን ወደ ቡልየን ዋጋ በግድ-ለመቀየር (Coerce)፣ በክፍል 4.2.2 ላይ እንደዚህ !!(teteqami && teteqami.authenticate('foobar'))
አድርገን የተጠቀምንበትን የአናጋ አናጋ ዘዴን መጠቀም ትችላላችሁ (ከዚህ በፊት፣ የቃለ አጋኖ !
ምክንያት በልምድ “ባንግ (bang)” ተብሎ እንደሚጠራ ተምረን ነበር)፡፡
በክፍል 7.3.3 ላይ የተጠቃሚ ቅርጸት የስህተት መልእክቶችን በመጠቀም የምዝገባ ስህተቶችን እንዳሳየን ተመልክተናል፤ እነዚህ ስህተቶችም ከአንድ የተወሰነ ንቅ መዝገብ ቁስ ጋር የተዛመዱ ናቸው፣ ይህ በንዲህ እንዳለ፣ ክፍለጊዜው የ‘ንቅ መዝገብ ቅርጸት ስላልሆነ ይህ ስልት በክፍለጊዜ ላይ አይሰራም፡፡ ስለዚህ ባልተሳካ የግብአት ሙከራ ጊዜ የሚከሰተውን ስህተት ለማሳየት አንድ መልእክትን በብልጪታ ውስጥ እናስቀምጣለን፡፡ ይህንን ችግር እንደነገሩ ለማቃለል የተደረገው የመጀመሪያው ሙከራ በዝርዝር 8.8 ላይ ይገኛል፣ ነገር ግን መስተካከል የሚገባው ነገር እንዳለ ከወዲሁ ልንገነዘብ ይገባል፡፡
app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
def new
end
def create
teteqami = Teteqami.find_by(emelekt: params[:session][:emelekt].downcase)
if teteqami && teteqami.authenticate(params[:session][:password])
# ተጠቃሚውን አስገባ እና ወደ ተጠቃሚው ማሳያ ገጽ አዘዋውር፡፡
else
flash[:danger] = 'ልክ ያልሆነ የኤመልእክት/የመሕለፈቃል ጥምረት' # ይሄን ያህል ትክክል አይደለም!
render 'new'
end
end
def destroy
end
end
በጣቢያው ገጽታ (ዝርዝር 7.29) ውስጥ ባለው የብልጪታ መልእክት ማሳያ ምክንያት የ flash[:danger]
መልእክት በራስሰር ሲታይ፤ በቡትስትራፕ ቅ.ቋ ምክንያት ደግሞ ጥሩ ቅጥን በራስሰር ያገኛል (ምስል 8.6)።
አለመታደል ሆኖ፣ በጽሑፍ እና በዝርዝር 8.8 ውስጥ ባለው አስተያየት ላይ እንደተገለጸው፣ ይህ ኮድ እንደተጠበቀው ያን ያህል ትክክል አይደለም። ገጹ ትክክል ይመስላል፣ ታዲያ ችገሩ ምንድን ነው? የሚል ጥያቄ ሊነሳ ይችላል፤ ችግሩ የብልጪታው ይዞታ በአንድ መጠይቅ ባለበት ላይ ቁሞ እንዲቀር መሆኑ ነው፣ በዝርዝር 7.27 ውስጥ ከተጠቀምንበት የ‘አዟዙር (redirect
) ዘዴ ማለት ከአንድ ማዟዟር በተለየ መልኩ፣ አንድ ዝግጁገጽታን በ‘ዓቅርብ (render
) እንደገና ማቅረቡ እንደ አዲስ መጠይቅ አይቆጠርም፡፡ በዚህ ምክንያትም ብልጪታው በቛሚነት በማንፈልገው ገጽ ላይ ሁሉ የብልጪታ መልእክቱን ማሳየቱን ይቀጥላል። ለምሳሌ:- አንድ ብቁ ያልሆነ የግብዓት መረጃን ብናስረክብ እና ከዚያ በኋላ የመነሻ ገጹ ላይ ጠቅ ብናደርግ፣ ብልጪታው ለሁለተኛ ጊዜ ይታያል (ምስል 8.7)። ይህንን ሳንካ የማስተካከሉ ተግባር ለክፍል 8.1.5 የተያዘ ስራ ይሆናል፡፡
በአፕልኬሽናችን ውስጥ አሁን ያለው አንድ ትንሽ ሳንካ፣ ትክክለኛ ያልሆነው የብልጪታ ባህርይ ነው፡፡ በሳጥን 3.3 ውስጥ ባሉት የፈተና መመሪያዎች መሰረት፣ ስህተቱ ሳይደጋገም ስህተቱን ለመያዝ አንድ ፈተናን መጻፍ የሚገባን ሁኔታ ይህ ነው፤ ስለሆነም ከመቀጠላችን በፊት ለግብዓት ቅጽ ማስረከቢያ አንድ አጪር የውህደት ፈተናን እንጽፋለን። ሳንካውን ከመሰነድ እና ምልሰቱን ከመከላከል ባሻገር፣ ይህ ለተጨማሪ የግብዓት እና የውጣት ውህደት ፈተናወች፣ የሚሆን አንድ ጥሩ መሰረትን ይጥልልናል፡፡
የአፕልኬሽናችን የግብዓት ባህርይን ለመፈተን አንድ የውህደት ፈተናን በማመንጨት እንጀምራለን፡-
$ rails generate integration_test teteqamis_gba
invoke test_unit
create test/integration/teteqamis_gba_test.rb
ከዚህ በመቀጠል፣ በምስል 8.6 እና በምስል 8.7 ላይ የሚታዩትን ቅደም ተከተሎች ለማግኘት አንድ ፈተና ያስፈልገናል፡፡ ለዚሁ ፈተና መሰረታዊ የሆኑት ቅደም ተከተሎች እነዚህ ናቸው፡-
params
) ተርታን በክፍለጊዜወች መንገድ ላይ ማስቀመጥ።
ከላይ የተጠቀሱትን ቅደም ተከተሎች ተግባራዊ የሚያደርገው አንድ ፈተና በዝርዝር 8.9 ውስጥ ይገኛል፡፡
test/integration/teteqamis_gba_test.rb
require 'test_helper'
class TeteqamisGbatTest < ActionDispatch::IntegrationTest
test "በማይሰራ መረጃ መግባት" do
get gba_path
assert_template 'sessions/new'
post gba_path, params: { session: { emelekt: "", password: "" } }
assert_template 'sessions/new'
assert_not flash.empty?
get root_path
assert flash.empty?
end
end
በዝርዝር 8.9 ውስጥ ያለውን ፈተና ካከልን በኋላ፣ የግብዓት ፈተናው ቀይመሆን አለበት:-
$ rails test test/integration/teteqamis_gba_test.rb
ይህ የ‘ሬይልስ ፈትን (rails test
) ዘዴን እና የፋይሉን ሙሉ መንገድ በመጠቀም፣ አንድ እንኮ የፈተና ፋይልን ብቻ እንዴት ማስኬድ እንደሚቻል ያሳያል።
በዝርዝር 8.9 ላይ ያለውን የወደቀ ፈተና ለማሳለፍ የሚቻልበት መንገድ አሁን ያለውን የ‘ብልጪታ (flash
) ዘዴን ለየት ያለ መልክ ባለው የ‘አሁን.ብልጪታ (flash.now
) ዘዴ በመተካት ሲሆን፣ ይህም በሚቀርቡ ገጾች ላይ የብልጪታ መልእክቶችን ለማሳየት ተብሎ የተነደፈ ነው፡፡ ከ‘ብልጪታ (flash
) ይዞታ በተቃራኒ መልኩ የ‘አሁን.ብልጪታ (flash.now
) ዘዴው፣ ልክ አንድ አዲስ ተጨማሪ መጠይቅ ከአሳሹ ሲመጣ ይዞታው ሁሉ ይጠፋል፣ ይህንንም በዝርዝር 8.9 ላይ ፈትነን ያረጋገጥነው ባህሪ ነው፡፡ በአዲሱ ብልጪታ ተተክቶ የተስተካከላው የአፕልኬሽኑ ኮድ በዝርዝር 8.11 ውስጥ ይታያል፡፡
app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
def new
end
def create
teteqami = Teteqami.find_by(emelekt: params[:session][:emelekt].downcase)
if teteqami && teteqami.authenticate(params[:session][:password])
# ተጠቃሚውን አስገባ እና ወደ ተጠቃሚው ማሳያ ገጽ አዘዋውር፡፡
else
flash.now[:danger] = 'ልክ ያልሆነ የኤመልእክት/የይለፍ ቃል ጥምረት'
render 'new'
end
end
def destroy
end
end
ከዚያ ሁለቱም ማለት የግብዓት የውህደት ፈተናው እና ሙሉው የፈተና ስብስቡ አረንጓዴመሆናቸውን ማረጋገጥ እንችላለን፡-
$ rails test test/integration/teteqamis_gba_test.rb
$ rails test
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
አሁን የኛ የግብዓት ቅጽ ብቁ ያልሆኑ ርካቦቶችን (ማስረከቦችን) ማስተናገድ ስለሚችል፤ ቀጣዩ ሂደት ብቁ ርካቦትን በትክክል በማስተናገድ ተጠቃሚን ማስገባት ነው። በዚህ ክፍል ውስጥ፣ አሳሹ ሲዘጋ ጊዜው በራስሰር በሚቃጠል በአንድ ጊዜያዊ የክፍለጊዜ ብስኩት ተጠቃሚው እንዲገባ እናደርጋለን። በክፍል 9.1 ላይ አሳሹ ከተዘጋ በኋላም እንኳ የሚቆዩ ክፍለጊዜወችን እናክላለን።
ክፍለጊዜወችን መተግበሩ በበርካታ መቆጣጠሪያወች እና ትይታዎች ላይ ጥቅም ላይ የሚውሉ በርካታ የሚዛመዱ ተግባሮችን መበየንን ያሳትፋል። ሩቢ እንደዚህ ያሉ ተግባሮችን በአንድ ቦታ ለመሰብሰብ አንድ ክፍለክፍል (module) የተባለ ቦታ እንደሚሰጥ በክፍል 4.2.4 ላይ እንደተመለከትን ታስታውሱ ይሆናል፡፡ ለምቾትም፣ የክፍለጊዜወች መቆጣጠሪያን በማመንጨት ወቅት አንድ የክፍለጊዜ ረጅ ክፍለክፍል በራስሰር መንጪቷል (ክፍል 8.1.1)፡፡ በተጨማሪም፣ እንደዚህ ያሉ ረጅወች በሬይልስ ትይታዎች ውስጥ በራስሰር ይካተታሉ፤ ክፍለክፍሉን በሁሉም መቆጣጠሪያወች መሰረተ ክፍል ውስጥ (ማለት የአፕልኬሽን መቆጣጠሪያ ውስጥ) በማካተት በኛ መቆጣጠሪያዎች ውስጥም እንዲገኙ ለማድረግ ዝግጅት እናደርጋለን (ዝርዝር 8.13)።2
app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
include SessionsHelper
end
ሁሉ ውቅረት ተጠናቋል፤ አሁን ተጠቃሚዎችን ለማስገባት የሚያስችለንን ኮድ ለመጻፍ ዝግጁ ነን፡፡
የ‘ግባ
ዘዴበሬይልስ በተበየነው የ‘ክፍለጊዜ (session
) ዘዴ እርዳታ ምክንያት፣ አንድ ተጠቃሚን የማስገባቱ ስራ እጅግ በጣም ቀላል ነው። (ይህ ዘዴ በክፍል 8.1.1 ውስጥ ከመነጨው ከክፍለጊዜወች መቆጣጠሪያ ጋር የማይመሳሰል እና ፍጹም የተለየ ነው።) ክፍለጊዜ‘ን (session
) ልክ እንደ አንድ ተርታ አድርገን መውሰድ እንችላለን፤ አናም እንደሚከተለው አድርገን ልንመድበው እንችላለን፡-
session[:teteqami_id] = teteqami.id
ይህ አንድ የተመሰጠረ የተጠቃሚ-መታወቂያን የያዘ አንድ ጊዜያዊ ብስኩትን በተጠቃሚው አሳሽ ውስጥ ያስቀምጣል። ይህም ክፍለጊዜ[ተጠቃሚ_መታወቂያ]‘ን (session[:teteqami_id]
) በመጠቀም በሚቀጥሉት ገጾች ላይ መታወቂያውን ፈልገን እንድናገኝ ያስችለናል። በ‘ብስኩቶች (cookies
) ዘዴ (ክፍል 9.1) ከተፈጠረ ቛሚ ብስኩት ተቃራኒ በሆነ መልኩ፣ በ‘ክፍለጊዜ (session
) ዘዴ የተፈጠረው ጊዜያዊ ብስኩት፣ ልክ አሳሹ ሲዘጋ ወዲያውኑ ጊዜው ይቃጠል እና ስራው ያከትማል። (አንዳንድ አሳሾች እንደዚህ ያሉ ክፍለጊዜወች እነበሩበት እንዲመለሱ፣ አንድ “ካቆምክበት ቀጥል (continue where you left off)” የተባለ በይነገጽን እንደ አንድ አማራጪ አድርገው ያቀርባሉ፣ ሬይልስ ግን በዚህ በይነገጽ ላይ ምንም አይነት ስልጣን የለውም። በእንደዚህ ባለ ሁኔታ ላይ፣ ከአፕልኬሽኑ ተዘግቶ ከተወጣ በኋላም እንኳ፣ የክፍለጊዜው ብስኩት ሊቆይ ይችላል። ይህንን ቅንብር ለአሳሻችሁ እንዴት አድርጋችሁ እንደምታደርጉ ለማወቅ ጉጉቱ ካደረባችሁ፣ የራሳችሁን ቴክኒካዊ ብልሃት መጠቀም ትችላላችሁ፡፡)
በተለያዩ ቦታዎች ላይ አንድ ዓይነት የማግባት ብልሃትን ለመጠቀም ስለፈለግን፣ በዝርዝር 8.14 ላይ እንደሚታየው፣ በክፍለጊዜወች ረጅ ውስጥ አንድ ግባ (gba
) የተባለ ዘዴን እንበይናለን፡፡
gba
) ተግባር። app/helpers/sessions_helper.rb
module SessionsHelper
# የቀረበ ተጠቃሚን ማግባት።
def gba(teteqami)
session[:teteqami_id] = teteqami.id
end
end
የ‘ክፍለጊዜ (session
) ዘዴን በመጠቀም የተፈጠሩት ጊዜያዊ ብስኩቶች በራስሰር የተመሰጠሩ ስለሆኑ በዝርዝር 8.14 ውስጥ ያለው ኮድ ጥብቅ ነው፣ እናም አንድ አጥቂ ከተመሰጠረው ስሪት መታወቂያውን የሚገምትበት ምንም አይነት መንገድ የለውም፡፡ ክፍለጊዜው አሁንም ለአንድ ክፍለጊዜ ጠለፋ ጥቃት ተጋላጪ ነው፤ አጥቂው የክፍለጊዜ መታወቂያ ቅጅውን በማግኘት ልክ እንደ ተጠቃሚው ሁኖ ለመግባት ሊጠቀምበት ይችላል (ይህ ሂደት “ክፍለጊዜን መልሶ ማጥቃት” (session replay attack) ተብሎ ይጠራል)። ይህ በ‘ክፍለጊዜ (session
) ዘዴ ለተጀመረው ጊዜያዊ ክፍለጊዜወች ላይ ብቻ ተፈጻሚ ይሆናል፤ የ‘ብስኩቶች (cookies
) ዘዴን በመጠቀም ለተፈጠሩ ቋሚ ክፍለጊዜወችን ግን ጉዳዩ እንደዚህ አይደለም፤ ቋሚ ብስኩቶች ለክፍለጊዜ ጠለፋ ጥቃት እጅግ የተጋለጡ ናቸው፤ ስለሆነም በምዕራፍ 9 ላይ በተጠቃሚው አሳሽ ላይ ስለምናስቀምጠው መረጃ በጣም መጠንቀቅ ይኖርብናል፡፡ እነዚህን ጉዳዮች በክፍል 9.1 ላይ በበለጠ እንነጋገርባቸዋለን፡፡
ይህ በእንዲህ እያለ፣ አንድ እኛ ልንመለከተው የሚገባ “የክፍለጊዜ ጥገና” (Session Fixation) በመባል የሚታወቅ ተዛማጅ ጥቃት አለ፡፡ ባጪሩ፣ በአጥቂው የታወቀ አንድ የክፍለጊዜ መታወቂያን አንድ ሌላ ተጠቃሚ እንዲጠቀምበት በማድረግ፣ አጥቂው ተጠቃሚውን ለማታለል ይቻላል፤ ይህም አጥቂው ክፍለጊዜውን እንዲጋራ ይፈቅድለታል። (ለበለጠ ዝርዝር በሬይልስ የጥበቃ ጽሑፍ መመሪያ ውስጥ “የክፍለጊዜ ጥገናን” ተመልከቱ፡፡) መፍትሄው በአጥቂው የተፈለገው መታወቂያ እንዲጸዳ እና አንድ አዲስ የተፈጠረ መታወቂያ በክፍለጊዜ ተርታው ውስጥ እንዲፈጠር፣ አጥቂው ከመግባቱ በፊት ክፍለጊዜውን ወዲያውኑ እንደገና ማስጀመር ይሆናል፤ ይህንንም ክፍለጊዜ_እንደገናአስጀምር (reset_session
) የተባለውን የሬይልስ አብሮገነብ ዘዴ በመጠቀም ተግባራዊ ማድረግ እንችላለን:-
reset_session
በዝርዝር 8.14 ውስጥ ከተበየነው የ‘ግባ (gba
) ዘዴ እና ከላይ ከተጠቀሰው የ‘ክፍለጊዜ_እንደገናአስጀምር (reset_session
) ውይይት ጋር ተጠቃሚውን ለማግባት እና ወደ ተጠቃሚው መገለጫ ገጽ ለማዘዋወር እንችል ዘንድ፣ አሁን የክፍለጊዜ የ‘ፍጠር (create
) ተግባርን ለማጠናቀቅ ዝግጁ ነን፡፡ ውጤቱ በዝርዝር 8.153 ውስጥ ይታያል፡፡
app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
def new
end
def create
teteqami = Teteqami.find_by(emelekt: params[:session][:emelekt].downcase)
if teteqami && teteqami.authenticate(params[:session][:password])
reset_session
gba teteqami
redirect_to teteqami
else
flash.now[:danger] = 'ልክ ያልሆነ የኤመልእክት/የይለፍ ቃል ጥምረት'
render 'new'
end
end
def destroy
end
end
ይህንን ማለት ከዚህ በፊት በክፍል 7.4.1 ውስጥ ያየነውን የተጠቀጠቀ የማዘዋውር ዘዴ አስተውሉ:-
redirect_to teteqami
ሬይልስ ይህንን ወደ ተጠቃሚው መገለጫ ገጽ በራስሰር ይለውጠዋል፡-
user_url(user)
በዝርዝር 8.15 ውስጥ ከተበየነው ከፍጠር (create
) ተግባር ጋር በዝርዝር 8.4 ውስጥ የተበየነው የግብዓት ቅጽ አሁን መስራት ይኖርበታል፡፡ ይህ ኮድ በአፕልኬሽኑ እይታ ላይ ምንም ዓይነት ለውጥ አያመጣም፤ ስለሆነም የአሳሽ ክፍለጊዜውን በቀጥታ መርምራችሁ መግባታችሁን ከማወቅ በስተቀር ሌላ መግባታችሁን የምታውቁበት ምንም ዓይነት መንገድ አይኖርም፡፡ ይበልጥ የሚታዩ ለውጦችን እውን ማድረጉ ልክ እንደ አንድ የመጀመሪያ ሂደት ይቆጠርልን ዘንድ፣ በክፍል 8.2.2 ውስጥ በክፍለጊዜው ውስጥ ያለውን መታወቂያ በመጠቀም የአሁንተጠቃሚውን ከውሂበጎታው ፈልገን እናገኛለን፡፡ በክፍል 8.2.3 ውስጥ ወደ አሁንተጠቃሚው መገለጫ የሚወስደውን ዓ.አ.ሃ.አን እና የግብዓት አገናኞቹን ወደ አፕልኬሽኑ ገጽታ እናመጣቸዋለን።
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
Expires
) ባሕሪ ዋጋ ምንድ ነው?
የተጠቃሚውን መታወቂያ በጥብቅ ጊዜያዊ ክፍለጊዜ ካስቀመጥን በኋላ፣ አሁን ተጠቃሚውን ተከታታይ ገጾች ላይ ፈልገን ለማግኘት የምንችልበት አቋም ላይ እንገኛለን፣ ይህንን ተግባራዊ ለማድረግም ከክፍለጊዜ መታወቂያው ጋር የሚዛመደውን ተጠቃሚ መፈለግ ስላለብን አንድ ዓሁን_ተጠቃሚ (ahun_teteqami
) የተባለ ዘዴን እንበይናለን። የ‘ዓሁን_ተጠቃሚ (ahun_teteqami
) ስራ እንደ:-
<%= ahun_teteqami.sim %>
እና
redirect_to ahun_teteqami
ያሉ ግንባታዎች እንዲገነቡ ማስቻል ነው። የአሁንተጠቃሚን ለመፈለግ ያለን አንዱ አማራጪ፣ ልክ የተጠቃሚ መገለጫ ገጽን ለማሳየት የተጠቀምንበትን የ‘ፈልግ (find
) ዘዴን መጠቀም ሊሆን ይችላል (ዝርዝር 7.5)፡-
Teteqami.find(session[:teteqami_id])
ነገር ግን የተጠቃሚው መታወቂያ በውሂበጎታው ውስጥ ካልኖረ የ‘ፈልግ (find
) ዘዴ አንድ ልዩነትን እንደሚያስነሳ በክፍል 6.1.4 ውስጥ እንደተመለከትነው ታስታውሱ ይሆናል፡፡ ይህ ልዩነት የማስነሳቱ ባህሪ በተጠቃሚው መገለጫ ገጽ ላይ ተገቢ ነው፤ ምክንያቱም ይህ ሁኔታ የሚፈጠረው መታወቂያው ብቁ ካልሆነ ነው፣ ነገር ግን አሁን ባለበት ሁኔታ ላይ የ‘ክፍለጊዜ[ተጠቃሚ_መታወቂያ] (session[:teteqami_id]
) ብዙውን ጊዜ ዋጋው ምንም (nil
) ይሆናል (ማለትም ላልገቡ ተጠቃሚዎች)፡፡ ይህንን ለማስተናገድ በ‘ፍጠር (create
) ዘዴ ውስጥ በኤመልእክት አድራሻ ለመፈለግ የተጠቀምንበትን የ‘ፈልግ_በ (find_by
) ዘዴን በ‘ኤመልእክት (emelekt
) ቦታ መታወቂያ‘ን (id
) በማስገባት እንደተመለከተው አድርገን እንጠቀምበታለን:-
Teteqami.find_by(id: session[:teteqami_id])
መታወቂያው ብቁ ካልሆነ ልዩነት ከማስነሳት ይልቅ፣ ይህ ዘዴ ምንም ነገር አለመሩን የሚያመለክተውን ምንም‘ን (nil
) ይመልሳል (እንደዚህ የሚባል ተጠቃሚ አለመኖሩን ለማመልከት)።
አሁን የ‘ዓሁን_ተጠቃሚ (ahun_teteqami
) ዘዴን እንደሚከተለው አድርገን መበየን እንችላለን:-
def ahun_teteqami
if session[:teteqami_id]
Teteqami.find_by(id: session[:teteqami_id])
end
end
(ሥልቱ ሂደቱን ሲጨርስ፣ የክፍለጊዜው ተጠቃሚ-መታወቂያ ካልኖረ በራስሰር ምንምን (nil
) ይመልሳል፤ እኛም የፈለግነው ይህንኑ ነው፡፡) ይህ በትክክል ይሰራል፣ ነገር ግን ለምሳሌ:- የ‘ዓሁን_ተጠቃሚ‘ው (ahun_teteqami
) በአንድ ገጽ ላይ ማለት የራሱ መገለጫ ገጽ ላይ ያሉትን አገናኞች ጠቅ ቢያደርግ፣ ጠቅ ያደረገውን ጊዜ ያህል ውሂበጎታውን ይመታዋል ማለት ነው፡፡ በዚያ ፈንታ፣ በሩቢ አሰራር ውስጥ የተለመደ አንድ ባህልን በመከተል የ‘ተጠቃሚ.ፈልግበ (Teteqami.find_by
) ውጤትን በአንድ ቅርፀ ተለዋዋጪ ላይ እናከማቻለን፣ ይህም የውሂበጎታውን ለመጀመሪያ ጊዜ ይመታ እና በተከታታዮቹ ጥሪዎች (Invocations)4 ላይ ግን ቅርፀ ተለዋዋጩን ወዲያውኑ ይመልሳል:-
if @ahun_teteqami.nil?
@ahun_teteqami = Teteqami.find_by(id: session[:teteqami_id])
else
@ahun_teteqami
end
በክፍል 4.2.2 ያየነውን የወይም (or )ስሌትን ||
በማስታወስ ይህንን እንደሚከተለው አድርገን እንዳዲስ መጻፍ እንችላለን:-
@ahun_teteqami = @ahun_teteqami || Teteqami.find_by(id: session[:teteqami_id])
የተጠቃሚ ቁስ በአንድ ቡልየን አውድ ውስጥ እውነት ስለሆነ፤ ፈልግ_በ (find_by
) ላይ የሚደረገው ጥሪ የሚከናወነው፣ የ‘ዓሁን_ተጠቃሚ (ahun_teteqami
) ዋጋ ገና ካልተመደበለት ብቻ ነው።
ቀደም ብለን የጻፍነው ኮድ የሚሰራ ቢሆንም፤ ሩቢያዊ ስነአጻጻፉ ግን ትክክል አይደለም፤ ሩቢያዊው የ‘ዓሁን_ተጠቃሚ (ahun_teteqami
) ምድባዊ ስነአጻጻፉ እንደዚህ ነው:-
@ahun_teteqami ||= Teteqami.find_by(id: session[:teteqami_id])
ይህ ግራ ሊያጋባ የሚችል ነገር ግን ብዙውን ጊዜ ለእንደዚህ አይነቱ አሰራር ጥቅም ላይ የሚውለውን የ ||=
(“የወይም እኩል ነው (or equals)”) ስሌትን ይጠቀማል (ሳጥን 8.1)፡፡
||=
ነው?ይህ ||=
(“የወይም እኩል ነው”) የምደባ ስሌት በሩቢ ቛንቛ ውስጥ የተለመደ አንድ የሩቢ ስነአጻጻፍ/ስነአነጋገር ነው፣ እናም የሬይልስ አበልጻጊ ለመሆን ምኞቱ ካላችሁ፣ ይህንን ስሌት በሚገባ ማወቁ አስፈላጊ ይሆናል፡፡ በመጀመሪያ ላይ ሲያዩት ድፍን ቅል ቢመስልም የወይም እኩል ነው ስሌትን በማነጻጸር ለመረዳት ግን በጣም ቀላል ነው፡፡
አንድ ተለዋዋጪ እየጨመረ የሚሄድበትን የጋራ ጥለት በአንክሮ በማስታዋል እንጀምራለን:-
ሀ = ሀ + 1
አብዛኛዎቹ የፕሮግራም ቋንቋዎች ለዚህ ስሌት አንድ ቆንጆ አቋራጪ የአጻጻፍ ስልትን ያቀርባሉ። በሩቢ (እና በሲ፣ በሲ++፣ በፐርል፣ በፓይታን፣ በጃቫ፣ ወዘተ) ላይ እንደሚከተለው ሊጻፍ ይችላል:-
ሀ += 1
በሌሎች ስሌቶች ላይም ተመሳሳይ የሆኑ አሰራሮች አሉ፡-
$ rails console >> ሀ = 1 => 1 >> ሀ += 1 => 2 >> ሀ *= 3 => 6 >> ሀ -= 8 => -2 >> ሀ /= 2 => -1
በእያንዳንዱ ስሌት
(+ ፣ * ፣ - እና /) ላይ የሁሉም ጥለት ሀ = ሀ ስሌት በ እና ሀ ስሌት= በ ነው፡፡
ሌላው የተለመደው የሩቢ ጥለት ደግሞ ምንም (nil)
ለሆነ ነገር አንድ ለውጥን፣ ምንም ላልሆነ ነገር ደግሞ ምንም ዓይነት ለውጥ የማያደርግ አንድ ምንም የሆነ ተለዋዋጪን ሆን ብሎ መሰየም ነው፡፡ በክፍል 4.2.2 ውስጥ የተመለከተውን የወይም ስሌት ||
እንደሚከተለው አድርገን መጻፍ እንችላለን፡-
>> @ፉ => nil >> @ፉ = @ፉ || "ባር" => "ባር" >> @ፉ = @ፉ || "ባዝ" => "ባር"
በአንድ ቡልየን አውድ ውስጥ፣ የምንም (nil)
ዋጋ ሁልጊዜ ሃሰት ስለሆነ ለ@ፉ
ቅርፀ ተለዋዋጪ መጀመሪያ ላይ እንደምታዩት የተመደበው ዋጋ ምንም ነው፤ እናም nil || "ባር"
የሚለው ግምገማ "ባር"
‘ን ይመልሳል፤ (ከላይ ያለውን የ@ፉ ቅርፀ ተለዋዋጪ የምንምን ዋጋ ለመስጠት ስንመድበው @ፉ = nil ያላደረግንበት ምክንያት በሬይልስ (በሩቢ) ውስጥ ሁልጊዜ ዋጋ ያልተሰጠው ቁስ ሁሉ በራስሰር ዋጋው ምንም፣ ማለት ኒል ስለሆነ ነው፡፡) በተመሳሳይ መልኩ የሁለተኛው ምደባ @ፉ || "ባዝ"
ሲሆን፣ ይህም በሌላ አባባል "ባር" || "ባዝ"
ማለት ነው፡፡ ይህም "ባር"
የሚለውን ዋጋ ሰቷል። ይህ የሆነበት ዋና ምክንያት፣ በቡልየን አውድ ውስጥ ካለ ምንም (nil)
እና ሃሰት (false)
በስተቀር ሌላው ነገር በሙሉ እውነት (true)
ስለሆነ ነው፡፡ በ ||
ካሉ ተከታታይ ሂሳበሃረጎች ውስጥ የመጀመሪያው ሂሳበሃረግ (በስተግራ በኩል ያለው) እውነት ከሆነ ሂሳበሃረጉ በቀጥታ ይቆማል። (ይህ የ ||
ሂሳበሃረግን ከግራ ወደቀኝ የምንመዝንበት እና በመጀመሪያው የእውነት ዋጋ የሂሳበሃረጉን የምናቆምበት አሰራር የአቋራጪ-ዙር ግምገማ (short-circuit evaluation) በመባል ይታወቃል፡፡ ይኸው መርህ ለ‘እና (&&
) ዓረፍተሐሳብም በአንድ አይነት መልኩ ይሰራል፣ ይሁን እንጅ በዚህ ሁኔታ ላይ ግን ሂሳበሃረጉ የሚቆመው የመጀመሪያውን የሃሰት (false)
ዋጋ ሲያገኝ ነው።)
በሬይልስ ሰሌዳ ውስጥ የተለያዩ ስሌቶችን በምናመዛዝንበት ጊዜ ይህ ጥለት @ፉ = @ፉ || "ባር"
የ ሀ = ሀ ስሌት በ
ጥለትን እንደሚከተል እና በስሌት
ተለዋዋጪ ቦታ ላይ ይህን ||
ስሌት ሲተካ እናያለን:-
ሀ = ሀ + 1 -> ሀ += 1 ሀ = ሀ * 3 -> ሀ *= 3 ሀ = ሀ - 8 -> ሀ -= 8 ሀ = ሀ / 2 -> ሀ /= 2 @ፉ = @ፉ || "ባር" -> @ፉ ||= "ባር"
ስለሆነም @ፉ = @ፉ || "ባር"
እና @ፉ ||= "ባር"
እኩል መሆናቸውን እናያለን፡፡ ይህ የአጻጻፍ ስልት በአሁንተጠቃሚ አውድ ውስጥ የሚከተለውን የአጻጻፍ ስልት መጠቀምን ይጠቁማል:-
@\kode{ahun\_teteqami} ||= Teteqami.find_by(id: session[:teteqami_id])
ይሄው !
(ቴክኒካዊ በሆነ መልኩ ሩቢ @ፉ
(ምንም (nil)
) ወይም (ሃሰት (false)
) ካልሆነ አላስፈላጊ የሆነ ብየናን ለማጥፋት @ፉ || @ፉ = "ባር"
የሚለውን ሂሳበሃረግ ይገመግማል፡፡ ይህ ሂሳበሃረግ ስለ ||=
ስርዓተ-ምልክቱ ምንም ዓይነት ማብራርያ አይሰጥም፤ ለዚህም ነበር ከዚህ በላይ በነበረው ውይይት ላይ አንድ ዓይነት የሆነውን የ @ፉ = @ፉ || "ባር"
ምሳሌን ለመመልከት የተገደድነው።)
ከዚህ በላይ የተወያየንበት ውጤትን በተግባር ላይ ማዋሉ በዝርዝር 8.16 ላይ የሚታየውን የዓሁን_ተጠቃሚ (ahun_teteqami
) ዘዴን ይሰጣል። (ክፍለጊዜ[ተጠቃሚ_መታወቂያ] (session[:teteqami_id]
) አጠቃቀም ላይ ትንሽ የኮድ መደጋገም ይታያል፣ ይህንን ድግግሞሽ ክፍል 9.1.2 ላይ ስንደርስ እናስወግደዋለን።)
app/helpers/sessions_helper.rb
module SessionsHelper
# የቀረበ ተጠቃሚን ማግባት።
def gba(teteqami)
session[:teteqami_id] = teteqami.id
end
# አንድ የገባ አሁንተጠቃሚን ይመልሳል (ካለ)።
def ahun_teteqami
if session[:teteqami_id]
@ahun_teteqami ||= Teteqami.find_by(id: session[:teteqami_id])
end
end
end
በዝርዝር 8.16 ውስጥ ባለውና ከሚሰራው የ‘ዓሁን_ተጠቃሚ (ahun_teteqami
) ዘዴ ጋር፣ አሁን በተጠቃሚው የግብዓት ሁኔታ ላይ በመመርኮዝ በአፕልኬሽናችን ላይ ለውጦችን የምናደርግበት አቋም ላይ ደርሰናል፡፡
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
Teteqami.find_by(id: ...)
) በሬይልስ ሰሌዳ ላይ በመጠቀም፣ ተዛማጅ ተጠቃሚ በማይኖርበት ጊዜ ምንምን (nil
) እንደሚመልስ አረጋግጡ፡፡
:teteqami_id
) የተባለ ቁልፍ የያዘ ክፍለጊዜ (session
) የተባለ አንድ ተርታን ፍጠሩ። ከዚያ ቅደም ተከተሉን አንድ ባንድ በመከተል የ ||=
ስሌቱ እንደተፈለገው መስራቱን አረጋግጡ፡፡
session
) አሰራርን በሰሌዳ ውስጥ መመልከት።
>> session = {}
>> session[:teteqami_id] = nil
>> @ahun_teteqami ||= Teteqami.find_by(id: session[:teteqami_id])
<እዚህ ላይ ምን ይፈጠራል?>
>> session[:teteqami_id]= Teteqami.first.id
>> @ahun_teteqami ||= Teteqami.find_by(id: session[:teteqami_id])
<እዚህ ላይ ምን ይፈጠራል?>
>> @ahun_teteqami ||= Teteqami.find_by(id: session[:teteqami_id])
<እዚህ ላይ ምን ይፈጠራል?>
የመጀመሪያው የግብዓት ተግባራዊ አሰራር፣ በግብዓት ሁኔታ ላይ በመመርኮዝ የገጽታውን አገናኞች መለወጥን ያሳትፋል። በተለይ፣ በምስል 8.8 ስእላዊ መግለጫ5 ላይ እንደሚታየው፣ ለመውጣት እና ለተጠቃሚ ማዘጋጃ፣ ሁሉንም ተጠቃሚዎች ለመዘርዘር እና ለአሁንተጠቃሚው መገለጫ ገጽ የሚሆኑ አገናኞችን እናክላለን፡፡ በምስል 8.8 ላይ የመውጫ እና የመገለጫ አገናኞች በአንድ ተቆልቋይ “መለያ” ምናሌ ውስጥ እንደሚታዩ ልብ በሉ፤ በቡትስትራፕ እንደዚህ አይነት ምናሌ እንዴት እንደሚሰራ በዝርዝር 8.19 ውስጥ እንመለከታለን፡፡
በዚህ ጊዜ፣ እኔ በበኩሌ አፕልኬሽኑ ከዚህ በላይ የተገለጹትን ባህሪወች መያዙን ለማረጋገጥ አንድ የውህደት ፈተና መጻፍን እመርጣለሁ። በሳጥን 3.3 ላይ እንደተገለጸው፣ የሬይልስ የፈተና መሳሪያዎች አሰራርን በደንብ እያወቃችሁ ስትመጡ፣ በመጀመሪያ ፈተናዎችን ለመጻፍ ከፍተኛ የሆነ ፍላጎት እያደረባችሁ ይመጣ ይሆናል፡፡ ይሁን እንጅ እንዲህ ዓይነቱ ፈተና በርካታ አዳዲስ ሃሳቦችን ያሳትፋል፣ ስለሆነም ለሱ የሚሆን አንድ የተወሰነ ክፍለ ጊዜ መስጠቱ የተሻለ ይሆናል (ክፍል 8.2.4)፡፡
በጣቢያው ገጽታ ውስጥ ያሉትን አገናኞች ለመለወጥ የሚያረዳን አንዱ መንገድ፣ በአንድ ክት ሩቢ ውስጥ አንድ የከሆነ-ካልሆነ ዓረፍተሐሳብን መጠቀምን ያሳትፋል፡፡ ይህም ተጠቃሚው ገብቶ ከሆነ አንድ የአገናኞች ስብስብን ካልሆነ ግን ሌላ የአገናኞች ስብስብን ያዘጋጃል፡-
<% if gebtual? %>
# ለገቡ ተጠቃሚዎች የሚሆኑ አገናኞች
<% else %>
# ላልገቡ ተጠቃሚዎች የሚሆኑ አገናኞች
<% end %>
ከላይ የተጻፈው ኮድ፣ አሁን መበየን የሚኖርብንን አንድ ገብቷልን? (gebtual?
) የተባለ የቡልየን ዘዴ መኖርን ይጠይቃል።
አንድ የአሁንተጠቃሚ በክፍለጊዜው ውስጥ ካለ፣ አንድ ተጠቃሚ ገብቷል ማለት ነው፤ ይህ ማለት የ‘ዓሁን_ተጠቃሚ (ahun_teteqami
) ዋጋ ምንም (nil
) አይደለም ማለት ነው፡፡ ይህንን ሁኔታ ለማረጋገጥ ደግሞ “አይደለም (not)” ስሌትን (ክፍል 4.2.2) መጠቀምን ይጠይቃል፣ ይህ ስሌት የሚጻፈውም የቃለ አጋኖ !
ምክንያትን በመጠቀም ሲሆን፣ በተለምዶም “ባንግ” ተብሎ ይጠራል/ይነበባል፡፡ የዚህ የ‘ገብቷልን? (gebtual?
) ዘዴ ግኝት በዝርዝር 8.18 ውስጥ ይታያል፡፡
gebtual?
) ረጅ ዘዴ። app/helpers/sessions_helper.rb
module SessionsHelper
# የቀረበ ተጠቃሚን ማግባት።
def gba(teteqami)
session[:teteqami_id] = teteqami.id
end
# አንድ የገባ አሁንተጠቃሚን ይመልሳል (ካለ)።
def ahun_teteqami
if session[:teteqami_id]
@ahun_teteqami ||= Teteqami.find_by(id: session[:teteqami_id])
end
end
# ተጠቃሚ ከገባ እውነት፣ ካልገባ ግን ሃሰትን ይመለሳል።
def gebtual?
!ahun_teteqami.nil?
end
end
ዝርዝር 8.18 ላይ ካከልነው ኮድ ጋር፣ አሁን አንድ ተጠቃሚ ከገባ የገጽታውን አገናኞች ለመለወጥ ዝግጁ ነን፡፡ አራት አዲስ አገናኞች አሉ፤ ከእነዚህ ውስጥ ሁለቱ ተቆርጠዋል (በምዕራፍ 10 ላይ ነፍስ እንዘራባቸዋለን።)
<%= link_to "ተጠቃሚወች", '#' %>
<%= link_to "ዝግጅቶች", '#' %>
የመውጫ አገናኙ፣ በዝርዝር 8.2 ውስጥ የተበየነውን የመውጫ መንገድ ይጠቀማል፡፡
<%= link_to "ይውጡ", wta_path, method: :delete %>
እዚህ ላይ የመውጫ አገናኙ አንድ የሃ.ጽ.ማ.ስ የሠርዝ (DELETE)
መጠይቅን6 ማቅረብ እንዳለበት የሚያዘውን አንድ የተርታ ነጋሪአሴትን እንደሚያሳልፍ ልብ በሉ።
(ዝርዝር 8.16 ውስጥ የተበየነውን የ‘ዓሁን_ተጠቃሚ (ahun_teteqami
) ዘዴን በመጠቀም) አንድ የመገለጫ አገናኝንም እንደሚከተለው አድርገን ማከል እንችላለን፡-
<%= link_to "መገለጫ", ahun_teteqami %>
እዚህ ጋር ከዚህ በላይ ያለውን ኮድ አንድ ግልጽ ጥሪን በ‘ተጠቃሚ_መንገድ (teteqami_path
) ላይ በመጥራት እንደሚከተለው አድርገን መጻፍ በቻልን ነበረ:-
<%= link_to "መገለጫ", teteqami_path(ahun_teteqami) %>
ይህም በሚገባ በሰራ፣ ነገር ግን ሬይልስ የ‘ዓሁን_ተጠቃሚ (ahun_teteqami
) አንድ የተጠቃሚ ቁስ መሆኑን ስለሚያውቅ እና በ‘ዓገናኝ (link_to
) አውድ ውስጥ የ‘ዓሁን_ተጠቃሚ‘ን (ahun_teteqami
) በራስሰር ወደ ‘ዓሁን_ተጠቃሚ (teteqami_path(ahun_teteqami)
) ስለሚቀይር እጥር ምጥን ያለውን ኮድ መርጠናል፡፡
በመጨረሻም፣ ተጠቃሚዎች ባልገቡበት ጊዜ፣ በዝርዝር 8.2 ውስጥ የተበየነውን የመግቢያ መንገድን፣ ከመግቢያ ቅጹ ጋር እንዲያገናኝ አንድ አገናኝን እንፈጥራለን:-
<%= link_to "ይግቡ", gba_path %>
ሁሉንም ነገር ባንድ ላይ በተግባር ማዋሉ በዝርዝር 8.19 ላይ እንደሚታየው የዘመነውን የራስጌ ከፊል ይሰጣል፡፡
app/views/layouts/_rasgie.html.erb
<header class="navbar navbar-fixed-top navbar-inverse">
<div class="container">
<%= link_to "ማሳያ አፕልኬሽን", root_path, id: "አርማ" %>
<nav>
<ul class="nav navbar-nav navbar-right">
<li><%= link_to "መነሻ", root_path %></li>
<li><%= link_to "እርዳታ", erdata_path %></li>
<% if gebtual? %>
<li><%= link_to "ተጠቃሚወች", '#' %></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
መለያ <b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><%= link_to "መገለጫ", ahun_teteqami %></li>
<li><%= link_to "ዝግጅቶች", '#' %></li>
<li class="divider"></li>
<li>
<%= link_to "ይውጡ", wta_path, method: :delete %>
</li>
</ul>
</li>
<% else %>
<li><%= link_to "ይግቡ", gba_path %></li>
<% end %>
</ul>
</nav>
</div>
</header>
ዝርዝር 8.19 ውስጥ ያለው የራስጌ ከፊል፣ አዲስ አገናኞችን ወደ ገጽታው በማካተት ሂደት ላይ፣ የቡትስትራፕ ተቆልቋይ ምናሌዎችን የመስራት ችሎታን ለመጠቀም አጋጣሚውን ተጠቅሟል።7 በተለይ እዚህ ላይ እንደ ተቆልቋይ (dropdown
)፣ ተቆልቋይ-ምናሌ (dropdown-menu
) ወዘተ ያሉ ልዩ የቡትስትራፕ ቅ.ቋ ክፍሎች የመካተት ጉዳይን አስተውሉ፡፡ የተቆልቋይ ምናሌውን ስራ ላይ ለማዋል የተበጀውን የቡትስትራፕ ጃቫስክሪፕት እና የጀኴይሪ ቤተኮዶችን አፕልኬሽናችን ውስጥ ማካተት ይኖርብናል (የቡትስትራፕ ጃቫስክሪፕት ቤተኮድ በዝርዝር 5.5 ውስጥ የ‘ቡትስትራፕ-ሳስ (bootstrap-sass)
እንቁ አካል ሁኖ በራስሰር አልተካተተም)።
በክፍል 5.2 ላይ የሬይልስ የንብረት ቧንቧመስመር ከዌብፓክ እና ከያርን ጋር በትይዩነት እንደሚሰራ በሰፊው ተብራርቷል፣ እናም ከላይ ያለውን ጃቫስክሪፕት ወደ አፕልኬሽናችን ለማካተት ሁለቱንም ማለት ዌብፓክን እና ያርንን ስራ ላይ ማዋል አለብን፡፡ የመጀመሪያው ሂደት የሁለቱም ማለት የጀኴይሪ እና የቡትስትራፕ ጃቫስክሪፕት ቤተኮዶችን አፕልኬሽናችን ላይ መጫን ነው:-
$ yarn add jquery@3.5.1 bootstrap@3.4.1
ጀኴይሪ በአፕልኬሽናችን ውስጥ እንዲገኝ ለማድረግ፣ የዌብፓክ አካባቢ ፋይልን ማረም እና በዝርዝር 8.20 ውስጥ የሚታየውን ይዘት ማከል ይኖርብናል፡፡
config/webpack/environment.js
const { environment } = require('@rails/webpacker')
const webpack = require('webpack')
environment.plugins.prepend('Provide',
new webpack.ProvidePlugin({
$: 'jquery/src/jquery',
jQuery: 'jquery/src/jquery'
})
)
module.exports = environment
በመጨረሻም፣ ጀኴይሪን ማስፈለግ እና በአፕልኬሽን.ጀኤስ (application.js
) ፋይል ውስጥ ቡትስትራፕን ማስመጣት አለብን፤ ይህንንም በዝርዝር 8.21 ላይ እንደሚታየው፣ በአፕልኬሽን.ጀኤስ (application.js
) ፋይል ውስጥ ካለው የ‘አስመጣ (import
) ክፍል በታች ማከል እንችላለን፡፡
app/javascript/packs/application.js
.
.
.
import "channels"
import "jquery"
import "bootstrap"
Rails.start()
Turbolinks.start()
ActiveStorage.start()
በዚህ ጊዜ፣ ባለፉት ሶስት ክፍለ ጊዜ ውስጥ የጻፍነው ኮድ8 ብቃትን ለመፈተን የመግቢያ መንገዱን በመጎብኘት ልክ እንደ አንድ ብቃት ያለው ተጠቃሚ ሁናችሁ መግባት አለባችሁ (የተጠቃሚስም misalei@railstutorial.org
‘ን እና መሕለፈቃሉን ደግሞ foobar
ብላችሁ መጠቀም ትችላላችሁ)። በሁለቱም ማለት ከዝርዝር 8.19 እና ከዝርዝር 8.21 ኮዶች ጋር በምስል 8.9 ላይ እንደሚታየው፣ የተቆልቋይ ምናሌውን እና ለገቡ ተጠቃሚዎች የሚያገለግሉ አገናኞችን ማየት አለባችሁ፡፡
አሳሻችሁን ሙሉ በሙሉ ካቆማችሁት/ከዘጋችሁት፣ አፕልኬሽኑ የግባት ሁኔታችሁን እንደሚረሳውም ማረጋገጥ መቻል አለባችሁ፤ ከዚህ በላይ የተገለጹትን ለውጦች ለማየት፣ እንደገና መግባት ይኖርባችኋል፡፡9
አሁን አንድ የሚሰራ ተቆልቋይ ምናሌ ስላለን፣ ለተንቀሳቃሽ መሳሪያዎች ጥቂት የንድፍ ማሻሻያዎችን ለማከል እድሉን እንጠቀማለን፣ በዚያም በክፍል 5.110 ላይ የተገባውን ቃል ኪዳን እንፈጽማለን፡፡ የዚህ ስልጠና መጀመሪያ ክፍል ላይ እንደተመለከተው፣ ይህ ስልጠና ድር በመንደፍ ላይ የሚሰጥ ስልጠና አይደለም፣ ስለሆነም የተንቀሳቃሽ አፑ ቆንጆ እይታ እንዲኖረው ለማድረግ የሚያስፈልጉትን አነስተኛ ለውጦችን ብቻ እናደርጋለን፣ ነገር ግን በበቅ.ቋ እና በገጽታ ላይ መሰረታዊ እውቀትን ለማግኘት የሚያስፈልገውን ተማር ላይ እንዴት አድርጋችሁ ተንቀሳቃሾችን ቅጥ ማስያዝ እንደምትችሉ የበለጠ ዝርዝር ማግኘት ትችላላችሁ፣ በተለይ ምዕራፍ 9 ላይ “የተንቀሳቃሽ መገናኛ መጠይቆች” የሚለውን ክፍል መመልከቱ ጠቃሚ ይሆናል፡፡
አንዳንድ ለተንቀሳቃሽ ተስማሚ ንድፎችን ተግባራዊ ለማድረግ የመጀመሪያው ሂደታችን የአሁኑን አፕልኬሽናችንን ልክ በአንድ ተንቀሳቃሽ መሳሪያ ውስጥ እንደሚታየው አድርጎ ማየት ነው፡፡ የጣቢያውን ይዞታ ለማየት አንዱ አማራጪ፣ አንድ ተንቀሳቃሽ-ስልክን መጠቀም ሊሆን ይችላል፣ ነገር ግን በተለይ የብልጸጋ አፕልኬሽኑ ከአንድ የደመና ቅ.ማ.አ የመግቢያ ግድግዳ በስተጀርባ ወይም በአንድ የሰፈር አውታረመረብ ላይ እየሄደ ከሆነ፣ ይህ ነገር አመች ላይሆን ይችላል (የሰፈር አውታረመረብ ብዙውን ጊዜ ውጪ ባሉ መሳሪያዎች ላይደረስ ይችላል)። ይበልጥ ምቹ የሆነው አንድ አማራጪ “Responsive Design Mode” በመባል የሚታወቀውን የሳፋሪ የድር አሳሽ ገጸባህሪን መጠቀም ነው።11 እሱን ለማንቃት በመጀመሪያ ወደ “Preferences” መሄድ ይፈለግባችኋል፣ ከዚያ በ “Advanced” ክፍል ውስጥ “Show Develop menu in menu bar” የሚለው ማመልከቻሳጥን ላይ ምልክት አድርጉ (ምስል 8.10)፡፡
በምስል 8.10 ውስጥ ካለው ውቅረት ጋር በምስል 8.11 ላይ እንደሚታየው፣ ምላሽሰጪው የንድፍ ቅዱ ሊነቃ ይችላል፡፡ ይህ ስልት በምስል 8.12 እንደሚታየው፣ በርከት ባሉና በተለያዩ ተንቀሳቃሽ መሳሪያዎች ላይ የአፕልኬሽኑን ይዞታ ልክ አሁን እንዳለው አድርጎ የማየት ችሎታን ይሰጠናል፡፡12
እስኪ አሁን ምስል 8.9 ላይ የመገለጫ ገጹ ልክ በአንድ ተንቀሳቃሽ መሳሪያ ላይ እንደሚታይ አድርገን እንመልከት፡፡ በምስል 8.13 ላይ እንደሚታየው፣ በአሁኑ ጊዜ የምናሌ አይነቶቹ በጥሩ ሁኔታ የተሰለፉ አይደሉም፣ እና ምናሌው ራሱ ከስክሪኑ አናት ላይ ሰፊውን ክፍል ወስዷል። ይህ በንዲህ እንዳለ፣ የግርጌው ዳሳሽ አገናኞቹ የማይሆን ቦታ ላይ ይገኛሉ፣ በተጨማሪም በግርጌው ውስጥ ካለው ሌላ አገናኝ ጋር በጣም ተጠጋግተዋል። እኛ የምናቃልላቸው ዋንኛ ችግሮችም እነዚህ ብቻ ይሆናሉ፤ እና ሁለቱንም ችግሮች አነስተኛ በሆነ ኮድ ማስተካከል እንችላለን።
ይህንን ተግባር ላይ ለማዋል የመጀመሪያ ሂደታችን የእይታማረፊያ (Viewport) ተብሎ የሚጠራውን አንድ ልዩ የ‘ባሻገር (meta
) መለያን ማከል ነው፤ ይህም አበልጻጊወችን በዴስክቶፕ እና በተንቀሳቃሽ ሞዴሎች13 መካከል እየለዋወጡ እንዲሰሩ ያስችላቸዋል፡፡ በአፕልኬሽኑ ዝግጁገጽታ ውስጥ የሚገባው ኮድ በዝርዝር 8.22 ውስጥ ይታያል፡፡
meta
) መለያ ማከል። app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title><%= mulu_arest(yield(:title)) %></title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
.
.
.
ምናሌውን ለማስተካከል፣ የተንቀሳቃሽ ሞድ በሚሆን ጊዜ አንድ “ሃምበርገር ምናሌ” ተብሎ-የሚጠራ የምናሌ ዓይነትን እንጠቀማለን (ምናሌው ሃምበርገርን ስለሚመስል ባጋጣሚ ይሄንኑ ስያሜ አግኝቷል)። ይህም በዝርዝር 8.2314 ላይ እንደሚታየው፣ ዝርዝር 8.19 ላይ ባለው የራስጌ ፋይል ላይ የተወሰኑ መንቀሻወችን ማከልን ያሳትፋል።
የዝርዝር 8.23 ውጤት በምስል 8.14 ላይ ይታያል፡፡ በምስል 8.15 እንደሚታየው፣ ሃምበርገር የሚመስለውን አዶ ጠቅ ወይም ጫን ማድረጉ ምናሌውን እንዲከፈት ያደርገዋል። ይህ በምስል 8.13 ከሚታየው ነባሪ ምናሌ ጋር ሲነጻጸር በጣም ጉልህ የሆነ መሻሻልን እንዳጎናጸፈ አስተውሉ፡፡
የመጨረሻ ሂደት ይሆንልን ዘንድ፣ በግርጌው ላይ ያለውን ችግር ለማስተካከል አንድ ትንሽ ቅ.ቋን እናክላለን። ይህንን ለማድረግ ዘዴውም ከዴስክቶፕ ኮምፒዩተሮች ይልቅ ለተንቀሳቃሽ መሳሪያዎች የተለያዩ የቅ.ቋ ደንቦችን ተግባር ላይ ለማዋል የሚያስችለውን አንድ የመገናኛ መጠይቅን (Media Query) መጠቀም ይሆናል፡፡ በአንድ የድር መመርመሪያ ውስጥ ከብዙ ሙከራ-እና-ስህተት በኋላ የተገኘው የመጨረሻ ውጤት በዝርዝር 8.2415 ውስጥ ይታያል። የመሳሪያው ስፋት ከ800 ፒክስል በታች በሚሆንበት ጊዜ አዲሱ ቅጥ ተግባር ላይ የሚውል መሆኑን ልታስተውሉ ይገባል፡፡ ይህ ስፋት በተንቀሳቃሽ መሳሪያዎች ዘንድ የተለመደ የመጨረሻ ገደብ ነው (“መግቻቦታ (Breakpoint)” በመባልም ይታወቃል)፡፡ በዝርዝር 8.24 ውስጥ ያለውን ቅጥ ተግባራዊ ለማድረግ አሳሹን እንደ አዲስ ከከፈትን በኋላ፣ አፕልኬሽናችን በምስል 8.16 ላይ እንደሚታየው ዓይነት ሁኖ ይታያል፡፡
በዚህ ተንቀሳቃሾችን ቅጥ የማድረጉ ጉዳይ ይጠናቀቃል፤ እናም በዚህ ክፍል ውስጥ ለተጨመሩ የገጽታ አገናኞች የተወሰኑ ፈተናወችን ለማከል አሁን ዝግጁ ነን።
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
ስኬታማ ለሆነ ግብዓት አፕልኬሽኑ በትክክል እንደሚሰራ በእጃችን ካረጋገጥን በኋላ፣ ዝም ብለን ከመቀጠላችን በፊት፣ ይህንን ባህሪ ለማረጋገጥ እና ምልሰቶችን ለመያዝ አንድ የውህደት ፈተናን እንጽፋለን፡፡ በዝርዝር 8.9 ውስጥ በሚገኘው ፈተና ላይ ግንባታውን እንቀጥል እና የሚከተሉት ድርጊቶች ቅደም ተከተልን ለማረጋገጥ ተከታታይ ሂደቶችን እንጽፋለን:-
እነዚህን ለውጦች ለማየት፣ ፈተናችን፣ ከዚህ በፊት እንደ ተመዝገበ ተጠቃሚ ሆኖ፣ እንደ አዲስ የሚገባ አንድ ተጠቃሚን ይፈልጋል፤ ይህ ማለት እንዲህ ያለ አንድ ተጠቃሚ ከድሮው በውሂበጎታው ውስጥ ግዴታ መኖር አለበት ማለት ነው፡፡ ይህንን ለማድረግ ነባሪው የሬይልስ አሰራር እቃወችን መጠቀም ነው፤ ይህም ሬይልስ ወደ ፈተና ውሂበጎታ የሚጫኑ መረጃዎችን የሚያደራጅበት አንዱ መንገድ ነው፡፡ የኤመልእክት ልዩነት ፈተናወቻችን ያልፉ ዘንድ፣ (ዝርዝር 6.31) ነባሪ የሆኑትን እቃወች መሰረዝ እንደነበረብን በክፍል 6.2.5 ላይ ተገንዝበን ነበር፡፡ አሁን ግን ያንን ባዶ ፋይል በራሳችን በተበጁ እቃወች ለመሙላት ዝግጁዎች ነን፡፡
በአሁኑ ሁኔታ ላይ፣ አንድ ብቁ ስም እና የኤመልእክት አድራሻ ሊኖረው የሚገባ አንድ ተጠቃሚ ብቻ እንፈልጋለን፡፡ ተጠቃሚውን ማስገባት ስለምንፈልግ፣ ለክፍለጊዜወች መቆጣጠሪያ የፍጠር (create
) ተግባር ከሚሰጠው መሕለፈቃል ጋር ለማነጻጸር አንድ ብቁ መሕለፈቃልን ማካተት ይኖርብናል፡፡ በምስል 6.9 ውስጥ የሚገኘውን የውሂብ ቅድን ስንመለከት ለተጠቃሚ እቃው አንድ የ‘መሕለፈቃል_ፈጪ (password_digest
) ባሕሪ መፍጠር አንዳለብን እንገነዘባለን፣ ይህንንም የራሳችን የሆነ አንድ ፈጪ (fech
) የተባለ ዘዴን በመበየን አናከናውነዋለን፡፡
በክፍል 6.3.1 ውስጥ እንደተገለጸው፣ የመሕለፈቃል ፍጪ የተፈጠረው ቢክሪይፕት (በ‘ጥብቅ_መሕለፈቃል_አለው (has_secure_password
) በኩል) የተባለውን ቤተኮድ በመጠቀም ነው፤ ስለሆነም አንድ አይነት ዘዴን በመጠቀም፣ የእቃ መሕለፈቃሉን መፍጠር ይኖርብናል፡፡ የጥብቅ መሕለፈቃል ኮድ ምንጪን በመመርመር ይህ ዘዴ እንደሚከተለው ሁኖ እናገኘዋለን:-
BCrypt::Password.create(hereg, cost: waga)
በዘዴው ውስጥ ያለው ሃረግ (hereg
) የሚከተፈው ሃረግ ሲሆን፣ ዋጋ (waga
) ደግሞ ክትፉን ለማስላት የሂሳብ ዋጋውን የሚወስን የዋጋ ሰሚአሴት (cost parameter) ነው። አንድ ከፍተኛ ዋጋን (በጣም የተወሳሰበ የምስጥር ስልተ-ቀመርን) መጠቀሙ፣ የተከተፈውን ሃረግ ተጠቅሞ ዋናውን/ኦርጅናሉን መሕለፈቃል ለማወቅ የሂሳብ ስሌቱን አዳጋች እንዲሆን ያደርገዋል። ይህም አንድ አፕልኬሽን በምርት ላይ በሚሆንበት ጊዜ አስፈላጊ የሆነ የጥበቃ ጥንቃቄ ነው፤ ነገር ግን እኛ በፈተናዎች ውስጥ የ‘ፈጪ (fech
) ዘዴው በተቻለ መጠን ፈጣን እንዲሆን እንፈልጋለን። የጥብቅ መሕለፈቃል ኮድ ምንጪም ለዚህ ስራ የሚውል አንድ መስመር ኮድ አለው፡-
waga = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
BCrypt::Engine.cost
በዝርዝር መረዳት የማያስፈልጋችሁ ይህ ግልጽ ያልሆነ ኮድ፣ ከዚህ በላይ የተገለጸውን ባህሪ በትክክል ያዘጋጃል፤ በአንድ አፕልኬሽን ውስጥ የፈተናወች ስራ በሚከናወንበት ወቅት፣ አነስተኛ የዋጋ ሰሚአሴትን (በአነስተኛ ደረጃ የተወሳሰበ ስልተ-ቀመርን) ሲጠቀም አንድ አፕልኬሽን በምርት ላይ በሚሆንበት ወቅት ደግሞ ከፍተኛ የሆነ የዋጋ ሰሚአሴትን (በጣም የተወሳሰበ ስልተ-ቀመርን) ይጠቀማል፡፡ (በክፍል 9.2 ውስጥ አሁን እንግዳ ስለሆነው ስርዓተ-ምልክት ?
-:
የበለጠ እንማራለን፡፡)
የ‘ፈጪ (fech
) ዘዴን ማስቀመጥ የምንችልባቸው በርካታ ቦታዎች አሉ፣ ነገር ግን በተጠቃሚ ቅርጸት ውስጥ በክፍል 9.1.1 ላይ ይህንኑ ዘዴ እንደገና ጥቅም ላይ የምናውልበትን አንድ አጋጣሚም አለ፡፡ ይህም ይህ ዘዴ በተጠቃሚዎች.አርቢ (teteqami.rb
) ፋይል ውስጥ መቀመጥ እንዳለበት ይጠቁማል፡፡ ፍጪው በሚሰላበት ጊዜ፣ የግድ የአንድ ተጠቃሚ ቁስን መድረስ ስለለለበት (በእቃዎች ፋይል ውስጥ እንዳለው ሁኔታ) የ‘ፈጪ (fech
) ዘዴውን ከራሱ ከተጠቃሚው ክፍል ጋር እናያይዘዋለን፣ ይህም ዘዴውን (በክፍል 4.4.1 ላይ በግልጽ እንዳየነው) አንድ የክፍል ዘዴ ያደርገዋል። ውጤቱ በዝርዝር 8.25 ውስጥ ይታያል፡፡
app/models/teteqami.rb
class Teteqami < ApplicationRecord
before_save { emelekt.downcase! }
validates :sim, presence: true, length: { maximum: 50 }
BQU_YE_EMELEKT_MEDEBEGNA_HISABEHEREG =/\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :emelekt, presence: true, length: { maximum: 255 },
format: { with:BQU_YE_EMELEKT_MEDEBEGNA_HISABEHEREG },
uniqueness: true
has_secure_password
validates :password, presence: true, length: { minimum: 6 }
# ለተሰጠው ሃረግ የተከተፈ ፍጪን ይመልሳል።
def Teteqami.fech(hereg)
waga = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
BCrypt::Engine.cost
BCrypt::Password.create(hereg, cost: waga)
end
end
በዝርዝር 8.25 ውስጥ ካለው የ‘ፈጪ (fech
) ዘዴ ጋር፣ አሁን በዝርዝር 8.26 ላይ እንደሚታየው፣ ለአንድ ብቁ ተጠቃሚ አንድ የተጠቃሚ እቃን ለመፍጠር ዝግጁ ነን፡፡
test/fixtures/teteqami.yml
michael:
sim: Michael Abnet
emelekt: michael@misalei.com
password_digest: <%= Teteqami.fech('mehlefeqal') %>
እዚህ ላይ እቃወች ክት ሩቢን በውስጣቸው ማካተትን እንደሚደግፉ ልትገነዘቡ ይገባል፤ ይህም ለሚፈተነው ተጠቃሚ ብቁ የመሕለፈቃል ፍጪን ለመፍጠር የሚያስችለንን ማለት:-
<%= Teteqami.fech('mehlefeqal') %>
የሚል ኮድን እንድንጠቀም ያስችለናል፡፡
ምንም እንኳን በ‘ ጥብቅ_መሕለፈቃል_አለው (has_secure_password
) የሚፈለገውን የ‘መሕለፈቃል_ፈጪ (password_digest
) ባሕሪ የበየንን ቢሆንም፣ አንዳንድ ጊዜ ጥሬውን (ምናባዊ) መሕለፈቃልን ማጣቀሱ አመች በሆነ ነበረ። ያለመታደል ሆኖ ግን ይህንን ስራ ከእቃወች ጋር ለማዘጋጀት የማይቻል ነገር ነው፤ እናም በዝርዝር 8.26 ላይ አንድ መሕለፈቃል (password
) የተባለ ባሕሪን ማከሉ፣ ሬይልስን በውሂበጎታው ውስጥ “እንደዚህ ያለ አምድ የለም” የሚል ቅሬታ እንደሚያሰማ ያደርገዋል (ይህም እውነት ነው)፡፡ ይህንንም የተለመደውን አሰራር በመከተል ሁሉም የእቃ ተጠቃሚዎች በፈተና ወቅት አንድ ዓይነት መሕለፈቃል ('mehlefeqal'
) እንደሚኖራቸው በማድረግ እናከናውነዋለን።
አንድ እቃን ከአንድ ብቁ ተጠቃሚ ጋር ከፈጠርን በኋላ፣ እሱኑ በአንድ ፈተና ውስጥ እንደሚከተለው አድርገን ፈልገን ማግኘት እንችላለን:-
teteqami = teteqamis(:michael)
እዚህ ላይ ተጠቃሚዎች (teteqamis
) ከተጠቃሚዎች-ያምል (teteqamis.yml
) ፋይል ጋር ሲያዛምድ፤ ማይክል (:michael
) የሚለው ወካይ ደግሞ በዝርዝር 8.26 ውስጥ ከሚታየው ቁልፍ ጋር ተጠቃሚውን ያጣቅሳል፡፡
በዝርዝር 8.27 ላይ እንደሚታየው፤ ከላይ ባለው የእቃ ተጠቃሚው ጋር፣ በዚህ ክፍል መጀመሪያ ላይ የተዘረዘሩትን ቅደም ተከተሎች ወደ ኮድ በመለወጥ አሁን ለገጽታው አገናኞች አንድ ፈተናን መጻፍ እንችላለን፡፡
test/integration/teteqamis_gba_test.rb
require 'test_helper'
class TeteqamisGbatTest < ActionDispatch::IntegrationTest
def setup
@teteqami = teteqamis(:michael)
end
test "በብቁ መረጃ መግባት" do
get gba_path
post gba_path, params: { session: { emelekt: @teteqami.emelekt,
password: 'mehlefeqal' } }
assert_redirected_to @teteqami
follow_redirect!
assert_template 'teteqamis/show'
assert_select "a[href=?]", gba_path, count: 0
assert_select "a[href=?]", wta_path
assert_select "a[href=?]", teteqami_path(@teteqami)
end
end
እዚህ ላይ የሚከተሉትን ኮዶች ተጠቅመናል:-
assert_redirected_to @teteqami
ይህ ትክክለኛውን የመዟዟር አድራሻ ለመፈተሽ ሲሆን፤ የሚከተለው ኮድ ደግሞ:-
follow_redirect!
የተዘዋወረውን ገጽ በትክክል ለመጎብኘት ነው። ዝርዝር 8.27 በገጹ ላይ ምንም ዓይነት የግባት መንገድ አገናኝ እንደለለ ዜሮን በመስጠት:-
assert_select "a[href=?]", gba_path, count: 0
ተጨማሪውን የ‘ቁጠር፡ 0 (count: 0
) አማራጪ በማካተት፣ ከተሰጠው ጥለት ጋር የሚዛመድ ዜሮ አገናኝ ይኖራል ብለን እንጠብቃለን፣ በማለት ለ‘መለያ_አረጋግጥ (assert_select
) ትእዛዝ እንሰጠዋለን። (ይህንን በዝርዝር 5.32 ውስጥ በትክክል ሁለት ተዛማጅ አገናኞች መኖራቸውን ከሚፈትሸው ከ‘ቁጠር፡ 2 (count: 2
) ስልት ጋር አነጻጽሩ፡፡)
የአፕልኬሽን ኮዱ ከድሮውም ይሰራ ስለነበረ፣ ይህ ፈተና ያለምንም ጥርጥር አረንጓዴመሆን አለበት:-
$ rails test test/integration/teteqamis_gba_test.rb
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
if teteqami
ከሚለው በኋላ አስተያየት በማድረግ፤ ኤመልእክቱን እና መሕለፈቃሉን ተጠቅመን ተጠቃሚውን ብናረጋግጥም እንኳን ፈተናው ግን እንደሚያልፍ አረጋግጡ፡፡ ለምን ፈተናው ያልፋል? የሚል ጥያቄ ሊነሳ ይችላል፤ ምክንያቱ በዝርዝር 8.9 ላይ የሰፈረው ፈተና አንድ ትክክለኛ የሆነ የተጠቃሚ ኤመልእክትን ሳይሆን፤ አንድ ትክክል ያልሆነ የተጠቃሚ መሕለፈቃልን ብቻ ስለሚፈትን ነው፡፡ በዝርዝር 8.30 ላይ እንደተመለከተው፣ በተጠቃሚዎች የመግቢያ ፈተና ላይ፣ አንድ ብቁ የኤመልእክትን በማከል ይህን አስፈሪ ቀዳዳ ድፈኑ፡፡ አሁን ባለንበት ደረጃ ላይ ፈተናው ቀይመሆኑን ካረጋገጣችሁ በኋላ፣ ከዚያ ፈተናውን አረንጓዴለማድረግ ካሁን በፊት ያደረጋችሁትን አስተያየት ካለበት ቦታ አስወግዱ። (ይህ ፈተና በጣም አስፈላጊ ስለሆነ፣ በክፍል 8.3 ላይ ወደ ዋናው ኮድ እናክለዋለን።)
&.
ተጠቀሙ። ይህ የሩቢ ገጸባህሪ በ‘ቁስ && (obj &&
) እና በ‘ቁስ.ዘዴ (obj.method
) ውስጥ ያለውን ተመሳሳይ ጥለት እንደዚህ obj&.method
አድርገን እጥር ምጥን እንድናደርገው ያስችለናል፡፡ በዝርዝር 8.30 ውስጥ ያሉት ፈተናወች ከተደረገው ለውጥ በኋላም ማለፋቸውን አረጋግጡ፡፡
app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
def new
end
def create
teteqami = Teteqami.find_by(emelekt: params[:session][:emelekt].downcase)
if teteqami # && teteqami.authenticate(params[:session][:password])
reset_session
gba teteqami
redirect_to teteqami
else
flash.now[:danger] = 'ልክ ያልሆነ የኤመልእክት/የይለፍ ቃል ጥምረት'
render 'new'
end
end
def destroy
end
end
test/integration/teteqamis_gba_test.rb
require 'test_helper'
class TeteqamisGbatTest < ActionDispatch::IntegrationTest
def setup
@teteqami = teteqamis(:michael)
end
test "በብቁ ኤመልእት እና ብቁ ባልሆነ መሕለፈቃል መግባት" do
get gba_path
assert_template 'sessions/new'
post gba_path, params: { session: { emelekt: ይህን_ሙሉ,
password: "ብቁ ያልሆነ" } }
assert_template 'sessions/new'
assert_not flash.empty?
get root_path
assert flash.empty?
end
.
.
.
end
ምንም እንኳን የማረጋገጫ ስርዓታችን አሁን እየሰራ ቢሆንም፤ አዲስ የተመዘገቡ ተጠቃሚዎች በነባሪነት መግባት ስለማይችሉ ግራ ሊጋቡ ይችላሉ፤ ተጠቃሚዎች ከተመዘገቡ በኋላ ወዲያውኑ እንዲገቡ ማስገደዱ እንግዳ ነገር ስለሆነ፣ የምዝገባው ሂደት አካል ይሆን ዘንድ፣ አዲስ ተጠቃሚዎች ልክ እንደተመዘገቡ በራስሰር እናስገባቸዋለን። ይህንን ባህሪ ለማስተካከል ማድረግ የሚኖርብን ነገር ቢኖር፣ በተጠቃሚዎች መቆጣጠሪያ የ‘ፍጠር (create
) ተግባር ውስጥ አንድ የ‘ግባ (gba
) ጥሪን ማከል ብቻ ነው፡፡17 በክፍል 8.2.1 ውስጥ የተወያየንበትን የክፍለጊዜ ጥገና ጥቃቶችን ለመከላከል፣ (ልክ በዝርዝር 8.15 ላይ እንዳደረግነው) ከማስገባታችን በፊት ወዲያውኑ አንድ የ‘ክፍለጊዜ_እንደገናአስጀምር (reset_session
) ጥሪንም አክለናል። ውጤቱ በዝርዝር 8.32 ውስጥ ይታያል፡፡
app/controllers/teteqamis_controller.rb
class TeteqamisController < ApplicationController
def show
@teteqami = Teteqami.find(params[:id])
end
def new
@teteqami = Teteqami.new
end
def create
@teteqami = Teteqami.new(teteqami_negariaseitoch)
if @teteqami.save
reset_session
gba @teteqami
flash[:success] = "እንኳን ወደ ማሳያ አፕልኬሽኑ በደህና መጡ!"
redirect_to @teteqami
else
render 'new'
end
end
private
def teteqami_negariaseitoch
params.require(:teteqami).permit(:sim, :emelekt, :password,
:password_confirmation)
end
end
በዝርዝር 8.32 ውስጥ ያለውን የኮድ ባህሪ ለመፈተን እና ተጠቃሚው መግባቱን ለመፈተሽ፣ ዝርዝር 7.31 ውስጥ አንድ መስመር የፈተና ኮድን ማከል እንችላለን፡፡ በዚህ አውድ ውስጥ በዝርዝር 8.18 ውስጥ ከተበየነው የ‘ገብቷልን? (gebtual?
) ረጅ ዘዴ ጋር ጎንለጎን የሚሄድ አንድ ገብ_ቷልን? (geb_tual?
) የተባለ ረጅ ዘዴን መበየን ጠቃሚ ሲሆን፤ ይህም በ (ፈተና) ክፍለጊዜው ውስጥ አንድ የተጠቃሚ-መታወቂያ ካለ እውነት‘ን (true
) ከሌለ ደግሞ ሃሰት‘ን (false
) የሚመልስ (ዝርዝር 8.33) ይሆናል፡፡ (የረጅ ዘዴወች በፈተናወች ውስጥ ስለማይገኙ በዝርዝር 8.18 ውስጥ የሚገኘውን የ‘ዓሁን_ተጠቃሚ (ahun_teteqami
) ረጅ ዘዴን መጠቀም አንችልም። የ‘ክፍለጊዜ (session
) ዘዴ ግን ሁሉም ላይ ስለሚገኝ በምትኩ እሱን እንጠቀማለን።) የፈተና ረጅ ዘዴው እና የክፍለጊዜወች ረጅ ዘዴወች አንድ ዓይነት ስም ኑሯቸው እርስ በእርስ እንዳይጋጩ፣ ገብቷልን? (gebtual?
) ብለን ከመሰየም ይልቅ ገብ_ቷልን? (geb_tual?
) ብለን እንሰይመዋለን።18 (በዚህ ሁኔታ ላይ ከፈለግን የክፍለጊዜወች ረጅውን በማካተት በቀጥታ የ‘ገብቷልን? (gebtual?
) ዘዴን ብቻ መጠቀም በቻልን ነብር፣ ነገር ግን ይህ ዘዴ ብስኩቶች በፈተናዎች ውስጥ እንዴት መስተናገድ እንዳለባቸው በሚያቀርቡት መስፈርት ምክንያት በምዕራፍ 9 ላይ ያለውን መሰናክል አያልፍም ስለሆነም፤ ይልቁንስ በሁሉም ጉዳዮች ላይ የሚሰራ አንድ ፈተና ላይ ያተኮረ ዘዴን እንበይናለን፡፡)
test/test_helper.rb
ENV['RAILS_ENV'] ||= 'test'
.
.
.
class ActiveSupport::TestCase
fixtures :all
# አንድ የፈተና ተጠቃሚ ከገባ እውነትን ይመለሳል።
def geb_tual?
!session[:teteqami_id].nil?
end
end
በዝርዝር 8.33 ውስጥ ባለው ኮድ፣ በዝርዝር 8.34 ላይ የተመለከተውን አንድ መስመር ኮድ በመጠቀም፣ ተጠቃሚው ከተመዝገበ በኋላ እንደገባ ማረጋገጥ እንችላለን፡፡
test/integration/teteqamis_temezgeb_test.rb
require 'test_helper'
class TeteqamisTemezgebTest < ActionDispatch::IntegrationTest
.
.
.
test "ብቁ የምዝገባ መረጃ" do
get temezgeb_path
assert_difference 'Teteqami.count', 1 do
post teteqamis_path, params: { teteqami: { sim: "Abnetawi Teteqami",
emelekt: "teteqami@misalei.com",
password: "password",
password_confirmation: "password" } }
end
follow_redirect!
assert_template 'teteqamis/show'
assert geb_tual?
end
end
በዚህ ጊዜ የፈተና ስብስቡ አረንጓዴመሆን አለበት:-
$ rails test
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
gba
) ዘዴ ፊት ላይ አስተያየት ብታደርጉ የፈተና ስብስቡ ምን ይሆናል? አረንጓዴ ወይስ ቀይ ?
በክፍል 8.1 ላይ እንደተብራራው፣ የማረጋገጫ ቅዳችን ተጠቃሚዎች በግልጽ እስካልወጡ ድረስ እንደገቡ ማቆየት ነው፡፡ በዚህ ክፍል ይህንን አስፈላጊ የመውጣት አቅም እናክላለን፡፡ የ“ይውጡ” አገናኝ አስቀድሞ ስለተበየነ (ዝርዝር 8.19) የተጠቃሚ ክፍለጊዜወችን ለማጥፋት የሚያስፈልገን ነገር ቢኖር፣ አንድ ብቁ የመቆጣጠሪያ ተግባርን መጻፍ ብቻ ነው።
የክፍለጊዜወች መቆጣጠሪያ ተግባሮች እስካሁን ድረስ የተለመደውን የሙሉው.ሁ.ማ የአሰራር ሂደትን ተከትለው ለመግቢያ ገጹ የ‘አዲስ (new
) ተግባርን እና ግባቱን ለማጠናቀቅ የ‘ፍጠር (create
) ተግባርን ተጠቅመዋል። አሁንም ይህንን ልምዳዊ አሰራር በመከተል ክፍለጊዜወችን ለመሰረዝ አንድ የ‘አጥፋ (destroy
) ተግባርን በመጠቀም የመውጣት ባህሪን እናካትታለን፡፡ በሁለቱም ማለት በዝርዝር 8.15 እና በዝርዝር 8.32 ውስጥ ከተጠቀምነው የመግቢያ አተገባበር በተለየ መልኩ፣ በአንድ ቦታ ብቻ እንወጣለን፤ ስለሆነም ተገቢውን ኮድ በቀጥታ በ‘አጥፋ (destroy
) ተግባር ላይ እናስቀምጣለን፡፡ ይህ ንድፍ (ከአንድ አነስተኛ የኮድ ማጣራት ጋር) የማረጋገጫ ፋብሪካውን ለፈተና ቀላል እንደሚያደርገው በክፍል 9.3 ላይ እናያለን።
መውጣት በዝርዝር 8.14 ውስጥ ያለውን የ‘ግባ (gba
) ዘዴ ክስተቶችን መቀልበስን ያሳትፋል።19 ይህንን ለማድረግ አንዱ መንገድ የተጠቃሚውን መታወቂያ ብቻ ለማስወገድ የክፍለጊዜውን የ‘ሰርዝ (delete
) ዘዴን መጠቀም ይሆናል:-
session.delete(:teteqami_id)
ይህ በእኛ ሁኔታ ላይ ይሰራል፣ ምክንያቱም ብቸኛው የአሁኑ ክፍለጊዜ ተለዋዋጩ ክፍለጊዜ[ተጠቃሚ_መታወቂያ] (session[:teteqami_id]
) ስለሆነ ነው፤ ሁሉም የክፍለጊዜ ተለዋዋጮች በሚወጡበት ጊዜ እንደገና መጀመራቸውን ለማረጋገጥ በይበልጥ የተሻለው አንድ ዘዴ ግን የ‘ክፍለጊዜ_እንደገናአስጀምር (reset_session
) ዘዴን መጠቀሙ ነው (ክፍል 8.2.1)፡፡ ይህ በዋናው ስልጠና ላይ በጪራሽ የሚያመጣብን ነገር የለም፣ በክፍል 9.3.2.1 ውስጥ ካለው አንድ መልመጃ ጋር ግን የተያያዘ ነው፤ እሱም የክፍለጊዜ ጠለፋን ለመከላከል አንድ የ‘:ክፍለጊዜ_ይስሙላ (:session_token
) ዋጋን ያክላል (ክፍል 8.2.1)፡፡ የ‘ክፍለጊዜ_እንደገናአስጀምር (reset_session
) ዘዴን መጠቀሙ፣ ለወደፊት ከሚመጣ እንደዚህ አይነት ሁኔታ አፕልኬሽናችን መጠበቁን ያረጋግጣል፡፡
ምንም እንኳን በአሁኑ ሁኔታ ላይ፣ ከመውጣት በኋላ በቀጥታ ወደ ስረ ዓ.አ.ሃ.አው ስለሚዟዟር የሚያመጣው ችግር ባይኖርም፣ ክፍለጊዜውን ዳግም ከማቀናበር በተጨማሪ፣ የአሁንተጠቃሚውንም ምንም (nil
) እናደርገዋለን፡፡20 በዝርዝር 8.36 ውስጥ እንደሚታየው፣ ግባ‘ን (gba
) እና የተዛመዱት ዘዴወችን በክፍለጊዜወች ረጅ ክፍለክፍል ውስጥ እንዳስቀመጥን ሁሉ፣ የ‘ውጣ (wta
) ዘዴንም እዛው እናስቀምጠዋለን፡፡
wta
) ዘዴ። app/helpers/sessions_helper.rb
module SessionsHelper
# የቀረበ ተጠቃሚን ማግባት።
def gba(teteqami)
session[:teteqami_id] = teteqami.id
end
.
.
.
# የአሁንተጠቃሚን ማስወጣት።
def wta
reset_session
@ahun_teteqami = nil
end
end
በዝርዝር 8.37 ውስጥ እንደሚታየው፣ የ‘ውጣ (wta
) ዘዴን በክፍለጊዜወች መቆጣጠሪያ የ‘አጥፋ (destroy
) ተግባር ውስጥ እንጠቀምበት ዘንድ፣ እሱን እዛው ውስጥ ማስቀመጥ እንችላለን፡፡
app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
def new
end
def create
teteqami = Teteqami.find_by(emelekt: params[:session][:emelekt].downcase)
if teteqami && teteqami.authenticate(params[:session][:password])
reset_session
gba teteqami
redirect_to teteqami
else
flash.now[:danger] = 'ልክ ያልሆነ የኤመልእክት/የይለፍ ቃል ጥምረት'
render 'new'
end
end
def destroy
wta
redirect_to root_url
end
end
የመውጣት ፋብሪካውን ለመፈተን፣ በዝርዝር 8.27 ላይ ለተጠቃሚ መግቢያ ፈተና የሚውሉ የተወሰኑ ተከታታይ ሂደቶችን ማከል እንችላለን፡፡ ለመውጫ መንገድ (ሰንጠረዥ 8.1) አንድ የ‘ሠርዝ (DELETE)
መጠይቅን ለመስጠት ሰርዝ‘ን (delete
) እንጠቀም እና ተጠቃሚው መውጣቱን እና ወደ ስረ ዓ.አ.ሃ.አ መዟዟርሩን እናረጋግጣለን፡፡ በተጨማሪ የመግቢያ አገናኝ እንደገና መታየቱን እና የመውጪያ እና የመገለጫ አገናኞቹ መጥፋታቸውንም እንፈትሻለን፡፡ አዲሶቹ ሂደቶች በዝርዝር 8.38 ውስጥ ይታያሉ፡፡
test/integration/teteqamis_gba_test.rb
require 'test_helper'
class TeteqamisGbatTest < ActionDispatch::IntegrationTest
def setup
@teteqami = teteqamis(:michael)
end
test "በብቁ ኤመልእት እና ብቁ ባልሆነ መሕለፈቃል መግባት" do
get gba_path
assert_template 'sessions/new'
post gba_path, params: { session: { emelekt: @teteqami.emelekt,
password: "ብቁ ያልሆነ" } }
assert_not geb_tual?
assert_template 'sessions/new'
assert_not flash.empty?
get root_path
assert flash.empty?
end
test "በብቁ መረጃ መግባት እና አከታትሎ መውጣት" do
get gba_path
post gba_path, params: { session: { emelekt: @teteqami.emelekt,
password: 'mehlefeqal' } }
assert geb_tual?
assert_redirected_to @teteqami
follow_redirect!
assert_template 'teteqamis/show'
assert_select "a[href=?]", gba_path, count: 0
assert_select "a[href=?]", wta_path
assert_select "a[href=?]", teteqami_path(@teteqami)
delete wta_path
assert_not geb_tual?
assert_redirected_to root_url
follow_redirect!
assert_select "a[href=?]", gba_path
assert_select "a[href=?]", wta_path, count: 0
assert_select "a[href=?]", teteqami_path(@teteqami), count: 0
end
end
(አሁን የ‘ገብ_ቷልን? (geb_tual?
) ዘዴ በፈተናችን ውስጥ ስላለን፣ በክፍለጊዜወች መንገድ ላይ ብቁ የሆነ መረጃን ካስቀመጥን በኋላ፣ ወዲያውኑ አንድ የ‘ገብ_ቷልን? አረጋግጥ (assert geb_tual?
) ፈተናን መሃል ላይ ጣል አርገናል፡፡ እንዲሁም፣ የዝርዝር 8.30 ውጤትን በማከል አንድ ተመሳሳይ የብቃት ማረጋገጫን እና በክፍል 8.2.4.1 ላይ ለተሰጠው መልመጃ የሚሆን መልስንም አክለናል።)
ከተበየነ እና ከተፈተነ የክፍለጊዜ የ‘አጥፋ (destroy
) ተግባር ጋር፣ የምዝገባ/የመግቢያ/የመውጫ የመጀመሪያ ስራ በድል ተጠናቋል፤ እና የፈተና ስብስቡም አረንጓዴመሆን አለበት፡-
$ rails test
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
እድሜ ለዚህ ምዕራፍ፣ የማሳያ አፕልኬሽናችን አንድ ሙሉ በሙሉ የሚሰራ የመግቢያ እና የማረጋገጫ ስርዓት አለው፡፡ በሚቀጥለው ምዕራፍ ላይ፣ ተጠቃሚዎችን ከአንድ ነጠላ የአሳሽ ክፍለ ጊዜ በላይ ረዘም ላለ ጊዜ የማስታወስ ችሎታን በማከል አፕልኬሽናችንን ወደላቀ ደረጃ እናሸጋግረዋለን።
ከመቀጠላችሁ በፊት፣ ለውጦቻችሁን ወደ ዋና ቅርንጫፍ አዋህዱ:-
$ rails test
$ git add -A
$ git commit -m "መሰረታዊ መግቢያን መተግብር"
$ git checkout main
$ git merge መሰረታዊ-መግቢያ
በመቀጠል ወደ ሩቅ ማስቀመጫ ግፉት:-
$ rails test
$ git push
መጨረሻ፣ እንደተለመደው ወደ ሃረኩ አሰማሩ:-
$ git push heroku
session
) ዘዴ በኩል ጊዜያዊ ብስኩቶችን በመጠቀም፣ ከአንድ ገጽ እስከ ሚቀጥለው ገጽ ድረስ ሁኔታን ጠብቆ ማቆየት እንደሚችል፣
flash.now
) ዘዴ በቀረቡ ገጾች ላይ ለብልጪታ መልእክቶች ጥቅም ላይ እንደሚውል፣
session
) ዘዴን በመጠቀም፣ አንድ ጊዜያዊ የሆነ ክፍለጊዜን ለመፍጠር፣ በአሳሹ ላይ የአንድ ተጠቃሚ-መታወቂያን በጥብቅ ማስቀመጥ እንደምንችል፣
የሠርዝ (DELETE)
መጠይቅን መስጠት አይችሉም፣ ሬይልስ ግን ጃቫስክሪፕትን በመጠቀም ይህንኑ ተግባር ያስኬዳል፡፡gba
) ዘዴን በድንገት ከሰረዝኩት በኋላም እንኳን፣ አንድ ጊዜ አረንጓዴየፈተና ስብስብን አግኝቼ አውቃለሁ። ይህ የሆነበት ምክንያት አፕልኬሽኑ ሙሉ በሙሉ ባይሰራም እንኳን፣ ፈተናወቹ ግን በተመሳሳይ ስም የተበየነውን የፈተና ረጅ በመጠቀም ይሰሩ ስለነበር ነው። ልክ እንደ ገብ_ቷልን? (geb_tual?
) በዝርዝር 9.24 ውስጥ የፈተና ረጅውን ግባ_እንደ (gba_ende
) የተባለ ዘዴን በመበየን ይህንን ችግር እናስወግዳለን፡፡@ahun_teteqami
) ቅርፀ ተለዋዋጪን የ‘ምንም (nil
) ዋጋን መመደቡ ከ‘አጥፋ (destroy
) ተግባር በፊት ከሆነ እና ምንም (nil
) ከሆነ በኋላ ወድያውኑ የማይዟዟር ከሆነ ችግር ያስከትላል። ይህ ሊሆን የማይችል የክስተት ጥምረት ነው፣ አሁን በዚህ አፕልኬሽን ላይ የቅርፀ ተለዋዋጩን አንድ የ‘ምንም (nil
) ዋጋን መመደቡ አስፈላጊ አይደለም፣ ነገር ግን ከጥበቃ ጋር በተዛመደ መልኩ የተሟላ ይሆን ዘንድ ጨምሬዋለሁ።