ምዕራፍ 8 መሰረታዊ መግቢያ

አሁን አዲስ ተጠቃሚዎች ለጣቢያችን መመዝገብ የሚችሉ ከሆነ (ምዕራፍ 7)፣ የተመዘገቡ ተጠቃሚዎችን ወደ ጣቢያችን የመግባት እና የመውጣት ችሎታ የመስጠቱ ጊዜ አሁን ነው ማለት ነው፡፡ በዚህ ምዕራፍ ውስጥ፣ አንድ መሰረታዊ ነገር ግን ሙሉ በሙሉ ተግባራዊ የሆነ የመግቢያ ስርዓትን እንተገብራለን፤ አሳሹ በተጠቃሚው እስኪዘጋ ድረስ አፕልኬሽኑ የግባት ሁኔታውን ያቆያል። ከትግባሬው የሚገኘው የማረጋገጫ ስርዓት፣ ጣቢያውን ለማበጀት እና በአሁንተጠቃሚው የግብዓት ሁኔታ እና ማንነት ላይ የተመሰረተ አንድ የፈቃድ ቅርጸትን ተግባራዊ ለማድረግ ያስችለናል፡፡ ለምሳሌ፣ በግብዓት/በውጣት አገናኞች እና በአንድ የመገለጫ አገናኝ የጣቢያውን ራስጌ ማዘመን እንችላለን፡፡

ምዕራፍ 10 ውስጥ፣ የገቡ ተጠቃሚዎች ብቻ የተጠቃሚ ማውጫ ገጽን እንዲጎበኙ፣ ትክክለኛው ተጠቃሚ ብቻ የራሱን መረጃ ለማረም ገጹን እንዲደርስ፣ አስተዳዳሪ ተጠቃሚዎች ብቻ ውሂበጎታው ላይ የሚገኙ ሌሎች ተጠቃሚዎችን እንዲሰርዙ የሚያስገድድ አንድ የጥበቃ ቅርጸትን ተግባር ላይ እናውላለን፡፡ በመጨረሻም በምዕራፍ 13 ላይ አንድ የግቡ ተጠቃሚ ማንነትን በመጠቀም፣ ከዚሁ ተጠቃሚ ጋር የተዛመዱ አጪርጽሑፎችን እንፈጥራለን፡፡ በምዕራፍ 14 ላይ ደግሞ የአሁንተጠቃሚውን የዚህን አፕልኬሽን ተጠቃሚዎች እንዲከተል እንፈቅዳለን (ስለዚህም አንድ የአጪርጽሑፎች ቀላቢን ይቀበላል፡፡)

በዚህ ምዕራፍ ውስጥ የሚሰራው የማረጋገጫ ስርዓት፣ በምዕራፍ 9 ላይ ለሚበለጽገው የላቀ የመግቢያ ስርዓት ልክ እንደ አንድ መሰረት ሆኖ ያገለግላል፡፡ አሳሹ በሚዘጋበት ጊዜ ተጠቃሚዎችን “ከመርሳት” ይልቅ፣ ምዕራፍ 9 ተጠቃሚዎችን በራስሰር መዘከርን ይጀምራል፣ እና ከዚያ በአንድ “ዘክረኝ” ማመልከቻሳጥን ዋጋ ላይ በመመርኮዝ ተጠቃሚዎችን በምርጫ ይዘክራል። በዚህ ምክንያትም፣ በምዕራፍ 8 እና በምዕራፍ 9 ውስጥ የበለጸጉት ተግባራት ሁሉ በአንድ ላይ ተጣምረው፣ በድር አራሰራር ላይ እጅግ የተለመዱትን ሶስቱን የመግቢያ ስርዓቶች ያበለጽጋሉ ማለት ነው፡፡

8.1 ክፍለጊዜወች

ሃ.ጽ.ማ.ስ ከቀደሙት መጠይቆች ማንኛውንም መረጃ መጠቀም የማይችል፣ እያንዳንዱን መጠይቅ ልክ እንደ አንድ ገለልተኛ ልውውጥ አድርጎ የሚቆጥር ሁኔታ አልባ ስምምነት ነው። ይህ ማለት፣ ተጠቃሚ ከአንዱ ገጽ ወደ አንዱ ገጽ በሚቀያይርበት ወቅት በሃይለ ጽሑፍ ማዘዋወሪያ ስምምነት በኩል የአንድ ተጠቃሚ ማንነትን የማስታወስ መንገድ የለም ማለት ነው፤ ስለሆነም የተጠቃሚ መግቢያ የሚያስፈልጋቸው የድር አፕልኬሽኖች አንድ ክፍለጊዜን መጠቀም ይኖርባቸዋል፤ ይህ ክፍለጊዜን የመጠቀም ዘዴ በሁለት ኮምፒዩተሮች መካከል አንድ ጊዜያዊ የሆነ ግንኙነትን ይፈጥራል (አንድ የድር አሳሽን የሚያስኬድ አንድ መደበኛ ኮምፒዩተርን፣ ከአንድ ሬይልስን የሚያስኬድ አገልጋይ ጋር መገናኘት እንደማለት ነው)።

በሬይልስ ውስጥ ክፍለጊዜወችን ለመተግበር በጣም የተለመደው ብልሃት፣ በተጠቃሚው አሳሽ ውስጥ መጠኑ አነስተኛ የሆነ ጽሑፍን የያዙ ብስኩቶችን ማስቀመጥን ያሳትፋል፡፡ ብስኩቶች ከአንዱ ገጽ ወደ ሚቀጥለው ገጽ ስለሚቆዩ እና መረጃዎችን ማከማቸት ስለሚችሉ (ለምሳሌ የተጠቃሚ-መታወቂያን)፤ በአፕልኬሽኑ የገባ ተጠቃሚን ከውሂበጎታ ፈልጎ የማግኘት ጥቅም ላይ ሊውሉ ይችላሉ፡፡ በዚህ ክፍል ውስጥ እና በክፍል 8.2 ውስጥ አሳሹ በሚዘጋብት1 ወቅት በራስሰር ጊዜያቸው የሚቃጠል ጊዜያዊ ክፍለጊዜወችን ለመስራት ክፍለጊዜ (session) የተባለውን የሬይልስ ዘዴን እንጠቀማለን፡፡ በቅርቡ በምዕራፍ 9 ላይ ከክፍለጊዜ ዘዴ ጋር የተዛመዱ የ‘ብስኩቶች (cookies) ዘዴወችን በመጠቀም ለረዥም ጊዜ መኖር የሚችሉ ክፍለጊዜወችን እንዴት መስራት እንደሚቻል እንማራለን።

ክፍለጊዜወችን ልክ እንደ አንድ ሙሉው.ሁ.ማ ሃብት አድርጎ መቅረጽ አስፈላጊ ነው፤ የመግቢያ ገጹን መጎብኘቱ ለአዲስ (new) ክፍለጊዜዎች አንድ ቅጽን ያቀርባል፣ ግብዓት አንድ ክፍለጊዜን ይፈጥራል (Create) ውጣት ደግሞ የተፈጠረውን ክፍለጊዜ ያጠፋል (Destroy)። የተጠቃሚ ሃብቱ ውሂብን ቋሚ አድርጎ ለማኖር አንድ የውሂበጎታ ደጀንን (በተጠቃሚ ቅርጸቱ በኩል) እንደተጠቀመው ሁሉ፣ የክፍለጊዜወች ሃብት ደግሞ ውሂብን ቋሚ አድርጎ ለማኖር ብስኩቶችን ይጠቀማሉ፤ በዚህ ምክንያትም አብዛኛው የግብዓት ስራ፣ በብስኩት ላይ የተመሰረተ የማረጋገጫ ፋብሪካን መገንባትን በማሳተፍ የመጣ ይሆናል፡፡ በዚህ ክፍል እና በሚቀጥለው ክፍል ላይ፣ አንድ የክፍለጊዜወች መቆጣጠሪያን፣ አንድ የግብዓት ቅጽን እና አስፈላጊ የሆኑ የመቆጣጠሪያ ተግባሮችን ለመስራት ዝግጅት እናደርጋለን፡፡ ከዚያ አስፈላጊውን የክፍለጊዜ አንቀሳቃሽ ኮድን በማከል የተጠቃሚ ግብዓትን በክፍል 8.2 ላይ እናጠናቅቃለን።

ከዚህ በፊት እንዳለፉት ምዕራፎች ሁሉ፣ ስራችንን በአንድ የርእስ ቅርንጫፍ ላይ እናካሂድ እና መጨረሻ ላይ ያደረግናቸውን ለውጦች ወደ ዋና ቅርንጫፉ እናዋህዳቸዋለን፡-

$ git checkout -b መሰረታዊ-መግቢያ

8.1.1 የክፍለጊዜወች መቆጣጠሪያ

የግብዓት እና የመውጣት አካላት፣ ከተወሰኑ የክፍለጊዜወች መቆጣጠሪያ የው.ሁ.ማ ተግባሮች ጋር ይዛመዳሉ፤ የግብዓት ቅጹ በ‘አዲስ (new) ተግባር ይስተናገዳል (በዚህ ክፍል ላይ ይሸፈናል)፤ በርግጥ የግብዓት ቅጽ የሚስተናገደው አንድ የ‘ዓስቀምጥ (POST) መልእክትን ወደ ፍጠር (create) ተግባር በመላክ ሲሆን (ክፍል 8.2)፤ የውጣት ቅጹ ደግሞ አንድ የሠርዝ (DELETE) መልእክትን ወደ አጥፋ (destroy) ተግባር በመላክ ይስተናገዳል (ክፍል 8.3)፡፡ (እነዚህ ተግባሮች ሰንጠረዥ 7.1 ላይ የተመለከቱትን የሃ.ጽ.ማ.ስ ግሶች ከሬይልስ ተግባሮች ጋር ያላቸውን ጥምረት እንደሚያሳይ ልታስተውሉ ይገባል።)

ስራችንን ለመጀመር፣ አንድ የክፍለጊዜ መቆጣጠሪያን ከአንድ አዲስ (new) ተግባር ጋር እናመነጫለን (ዝርዝር 8.1)።

ዝርዝር 8.1: የክፍለጊዜወች መቆጣጠሪያን ማመንጨት።
$ rails generate controller Sessions new

(የ‘አዲስ (new) ተግባርን ማካተቱ ትይታዎችንም ያመነጪልናል፣ ለዚህም ነው እዚህ ላይ ከትይታዎች ጋር የማይዛመዱትን የ‘ፍጠር (create) እና የ‘አጥፋ (destroy) ተግባሮችን ያላካተትነው፡፡) እቅዳችን በክፍል 7.2 ላይ ያደረግነውን የምዝገባ ገጽ ቅድን በመከተል፣ በምስል 8.1 ስእላዊ መግለጫ ላይ እንደሚታየው፣ አዲስ ክፍለጊዜወችን ለመፍጠር አንድ የግብዓት ቅጽን መፍጠር ነው፡፡

images/figures/login_mockup
ምስል 8.1: አንድ የግብዓት ቅጽ ስእላዊ መግለጫ።

የተጠቃሚዎች ሃብት ልዩ የሆነ የ‘ሃብቶች (resources) ዘዴን ተጠቅሞ ሁሉንም የሙሉው.ሁ.ማ ማዘዋወሪያ ስብስቦችን በራስሰር ፈጥሮ ነበረ (ዝርዝር 7.3)፤ ይሁን እንጅ የክፍለጊዜወች ሃብት ሶስት የተሰየሙ ማዘዋወሪያወች ብቻ ይኖሩታል፤ እነሱም በ‘ግባ (gba) ማዘዋወሪያ የሚስተናገዱ (የ‘ዓግኝ (GET)) እና የ‘ዓስቀምጥ (POST) መጠይቆች፤ እና በ‘ውጣ (wta) ማዘዋወሪያ የሚስተናገድ የ‘ሠርዝ (DELETE) መጠይቅ ናቸው። ውጤቱ በዝርዝር 8.2 ውስጥ ይታያል (በ‘ሬይልስ መቆጣጠርያ አመንጪ (rails generate controller) ትእዛዝ የመነጩ አላስፈላጊ የሆኑ ማዘዋወሪያወችንም ይሰርዛል)፡፡

ዝርዝር 8.2: የክፍለጊዜወችን መደበኛ የሙሉው.ሁ.ማ ተግባሮችን ለማግኘት አንድ ሃብትን ማከል። ቀይ 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 ላይ የክፍለጊዜ መቆጣጠሪያ ስናመነጪ አብሮ የመነጨው የክፍለጊዜ ፈተና ላይ አንድ አዲስ የግብዓት ማዘዋወሪያ በማከል እናዘምነዋለን።

ዝርዝር 8.3: የክፍለጊዜወች መቆጣጠሪያ ፈተናው፣ የግብዓት ማዘዋወሪያውን እንዲጠቀም ማዘመን። አረንጓዴ 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 አንድ ክፍለጊዜን መሰረዝ (ውጣት)
ሰንጠረዥ 8.1: ዝርዝር 8.2 ውስጥ በክፍለጊዜው ደንቦች የተሰጡ ማዘዋወሪያወች።

አሁን ብዙ የተበጁ ስዩም ማዘዋወሪያወችን በአፕልኬሽናችን ላይ ስለጨመርን፣ የ‘ሬይልስ-ማዘዋወሪያዎች (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

ውጤቱን በዝርዝር ለመረዳት መሞከሩ ይሄን ያህል አስፈላጊ አይደለም፤ ነገር ግን በዚህ መንገድ ያሉትን ማዘዋወሪያወች መመልከቱ በአፕልኬሽናችን የሚደገፉ ተግባሮችን ለመመልከት አንድ አጠቃላይ የሆነ ርዴትን ይሰጠናል።

መልመጃዎች

የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።

የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡

  1. በ‘ዓግኝ ግባ_መንገድ (GET gba_path) እና በ‘ዓስቀምጥ ግባ_መንገድ (POST gba_path) መካከል ያለው ልዩነት ምንድን ነው?
  2. የ‘ሬይልስ ማዘዋወሪያዎች (rails routes) ውጤትን ፈልግ (grep) ወደተባለው ትእዛዝ በቱቦ በማሳለፍ (Piping)፣ ከተጠቃሚው ሃብት ጋር የሚዛመዱትን ማዘዋወሪያወች በሙሉ ዘርዝሩ። እያንዳንዱ ሃብት ስንት ማዘዋወሪያወች አሉት? ጠቃሚ ምክር:- የዚህን መልስ በቀላሉ ለማግኘት በማዘዥያ መስመር ላይ መሰረታዊ እውቀትን ለማግኘት የሚያስፈልገውን ትምህርት ተማርውስጥ ስለ ግሬፕ (grep) የሚያስተምረውን ክፍል ተመልከቱ፡፡

8.1.2 ግብዓት ቅጽ

አስፈላጊ የሆነውን መቆጣጠሪያ እና ማዘዋወሪያ ከበየንን በኋላ፤ አሁን የአዲስ ክፍለጊዜ ማለትም የግብዓት ቅጽ ትይታን እንሞላለን፡፡ በምስል 8.1 ላይ የተመለከውን ስእላዊ መግለጫ ምስል 7.12 ላይ ከተመለከተው ስእላዊ መግለጫ ጋር ብናነጻጽር፣ የምዝገባ ቅጹ አራት መስኮች ሲኖሩት የግብዓት ቅጹ ግን ሁለት (የኤመልእክት እና የመሕለፈቃል) መስኮችን ከመያዙ በስተቀር የግብዓት ቅጹ ከምዝገባ ቅጹ ጋር ተመሳሳይ እንደሆነ እንገነዘባለን።

ምስል 8.2 ላይ እንደሚታየው፣ የግብዓት መረጃው ብቁ ካልሆነ የግብዓት ገጹን መልሰን ማቅረብ አና አንድ የስህተት መልእክትን ማሳየት እንፈልጋለን። በክፍል 7.3.3 ውስጥ የስህተት መልእክቶችን ለማሳየት አንድ የስህተት መልእክቶች ከፊልን ተጠቅመን ነበር፤ እነዛ የስህተት መልእክቶችም በ‘ንቅ መዝገብ ተዘጋጅተው በራስሰር እንደሚቀርቡም ተመልክተን ነበር። ይህ ክፍለጊዜ ግን የ‘ንቅ መዝገብ ቁስ ስላልሆነ እና ክፍለጊዜውን በመፍጠር ላይ የሚከሰቱ ስህተቶች ላይ ስለማይሰራ፣ ስህተቱን ልክ እንደ አንድ የብልጪታ መልእክት አድርገን እናቀርበዋለን።

images/figures/login_failure_mockup
ምስል 8.2: የግብዓት አለመሳካትን የሚያሳይ አንድ ስእላዊ መግለጫ።

የምዝገባ ቅጹ የ‘ቅጽ_ጋር (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 ውስጥ እንደሚታየው ይሆናል፡፡

ዝርዝር 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 ውስጥ ይህንን እንከን እንከነ ቢስ እናደርገዋለን፡፡)

images/figures/login_form
ምስል 8.3: የግብዓት ቅጽ።

በቅጹ የመነጨው የሃ.ጽ.መ.ቋ ኮድ በዝርዝር 8.5 ላይ ቁልጪ ብሎ ይታያል፡፡

ዝርዝር 8.5: ዝርዝር 8.4 የተመረተው የመግቢያ ቅጹ ሃ.ጽ.መ.ቋ።
<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] ተርታ ውጤትን እንደሚያስገኝ መገመት ትችሉ ይሆናል፡፡

መልመጃዎች

የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።

የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡

  1. ዝርዝር 8.4 ውስጥ የተበየነው ቅጽ ላይ የቀረቡ ርክቦች ወደ ክፍለጊዜ መቆጣጠሪያ ፍጠር (create) ተግባሩ ይዘዋወራሉ። ይህ በንዲህ እያለ፣ ሬይልስ ይህንን ለማድረግ እንዴት ያውቃል? ጠቃሚ ምክር:- የዚህን መልስ ለማግኘት መጀመሪያ ሰንጠረዥ 8.1 ላይ ከዚያ ዝርዝር 8.5 ላይ የመጀመሪያውን መስመር ተመልከቱ፡፡

8.1.3 አንድ ተጠቃሚን መፈለግ እና ማረጋገጥ

በለፈው ክፍለ ጊዜ ተጠቃሚዎችን ለመፍጠር (ለመመዝገብ) የመጀመሪያው ቅድመ ሁኔታ ብቁ ያልሆኑ የቅጽ መረጃ ግብዓቶችን በወጉ ማስተናገድ ነበር። አሁንም ለክፍለጊዜወች ፈጠራ (ግብዓት) ያንኑ ማለት ብቁ ያልሆኑ የቅጽ መረጃ ግብዓቶችን ጥጋቸውን በማስያዝ እንጀምራለን፡፡ አንድ ቅጽ በሚረከብበት ጊዜ ምን እንደሚከሰት በመገምገም እንጀምር እና ከዚያ በግብዓት ጊዜ የሚከሰቱትን አለመሳካቶች ቅጹ ላይ ጠቃሚ የሆነ መረጃ ለተጠቃሚው ለማሳየት፣ (ልክ ምስል 8.2 ላይ እንደሚታየው ስእላዊ መግለጫ) አጋዥ የሆኑ የስህተት መልእክቶችን እናዘጋጃለን፤ ከዚያ በኤመልእክት/የመሕለፈቃል ጥምረት ብቃት ላይ በመመርኮዝ የእያንዳንዱን የግባት ርካቤ በመገምገም፣ ለስኩ ግብዓት መሰረት እናስቀጣለን (ክፍል 8.2)።

ለክፍለጊዜወች መቆጣጠሪያ የ‘ፍጠር (create) እና የ‘አጥፋ (destroy) ተግባሮችን ከ‘አዲስ (new) ተግባር ጋር በመበየን እንጀምራለን (ዝርዝር 8.6)፡፡ በዝርዝር 8.6 ውስጥ ያለው የ‘ፍጠር (create) ተግባር አዲስ (new) ትይታ ከማቅረብ በቀር ሌላ ምንም ነገር አያደርግም፤ ይሁን እንጅ እኛን ለማስጀመር ግን በቂ ነው፡፡ የ/ክፍለጊዜወች/አዲስ (/sessions/new) ቅጽን ማስረከቡ በምስል 8.4 እና በምስል 8.5 ላይ የሚታዩትን ውጤቶች ይሰጣል፡፡

ዝርዝር 8.6: የክፍለጊዜወች የ‘ፍጠር (create) ተግባር በኩር ስሪት። app/controllers/sessions_controller.rb
class SessionsController < ApplicationController

  def new
  end

  def create
    render 'new'
  end

  def destroy
  end
end
images/figures/initial_failed_login
ምስል 8.4: ያልተሳካው በኩሩ የግብዓት ሙከራ ከዝርዝር 8.6 የ‘ፍጠር (create) ተግባር ጋር።
images/figures/initial_failed_login_debug
ምስል 8.5: ምስል 8.4 ላይ የተገኘውን የአርም መረጃ አጢኖ መመልከት፡፡

ምስል 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 እንደተመለከተው ሊጠቃለል ይችላል፡፡

ዝርዝር 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
ሰንጠረዥ 8.2: በተጠቃሚ እና በተጠቃሚ.አረጋግጥ(…) (user && user.authenticate(…)) ላይ ሊሆኑ የሚችሉ ውጤቶች።

መልመጃዎች

የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።

የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡

  1. የሬይልስ ሰሌዳን በመጠቀም፣ በሰንጠረዥ 8.2 ውስጥ የተዘረዘሩትን የቡልየን ዋጋዎች ለማረጋገጥ መጀመሪያ ላይ ያለውን ዋጋ teteqami = nil እና teteqami = Teteqami.first በማድረግ ጀምሩ። ጠቃሚ ምክር:- የዚህን መልስ በቀላሉ ለማግኘት፣ ውጤቱን ወደ ቡልየን ዋጋ በግድ-ለመቀየር (Coerce)፣ በክፍል 4.2.2 ላይ እንደዚህ !!(teteqami && teteqami.authenticate('foobar')) አድርገን የተጠቀምንበትን የአናጋ አናጋ ዘዴን መጠቀም ትችላላችሁ (ከዚህ በፊት፣ የቃለ አጋኖ ! ምክንያት በልምድ “ባንግ (bang)” ተብሎ እንደሚጠራ ተምረን ነበር)፡፡

8.1.4 አንድ መልእክትን በብልጪታ ማቅረብ

ክፍል 7.3.3 ላይ የተጠቃሚ ቅርጸት የስህተት መልእክቶችን በመጠቀም የምዝገባ ስህተቶችን እንዳሳየን ተመልክተናል፤ እነዚህ ስህተቶችም ከአንድ የተወሰነ ንቅ መዝገብ ቁስ ጋር የተዛመዱ ናቸው፣ ይህ በንዲህ እንዳለ፣ ክፍለጊዜው የ‘ንቅ መዝገብ ቅርጸት ስላልሆነ ይህ ስልት በክፍለጊዜ ላይ አይሰራም፡፡ ስለዚህ ባልተሳካ የግብአት ሙከራ ጊዜ የሚከሰተውን ስህተት ለማሳየት አንድ መልእክትን በብልጪታ ውስጥ እናስቀምጣለን፡፡ ይህንን ችግር እንደነገሩ ለማቃለል የተደረገው የመጀመሪያው ሙከራ በዝርዝር 8.8 ላይ ይገኛል፣ ነገር ግን መስተካከል የሚገባው ነገር እንዳለ ከወዲሁ ልንገነዘብ ይገባል፡፡

ዝርዝር 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)።

images/figures/failed_login_flash
ምስል 8.6: ለተጨናገፈው ግብዓት አንድ የብልጪታ መልእክት።

አለመታደል ሆኖ፣ በጽሑፍ እና በዝርዝር 8.8 ውስጥ ባለው አስተያየት ላይ እንደተገለጸው፣ ይህ ኮድ እንደተጠበቀው ያን ያህል ትክክል አይደለም። ገጹ ትክክል ይመስላል፣ ታዲያ ችገሩ ምንድን ነው? የሚል ጥያቄ ሊነሳ ይችላል፤ ችግሩ የብልጪታው ይዞታ በአንድ መጠይቅ ባለበት ላይ ቁሞ እንዲቀር መሆኑ ነው፣ በዝርዝር 7.27 ውስጥ ከተጠቀምንበት የ‘አዟዙር (redirect) ዘዴ ማለት ከአንድ ማዟዟር በተለየ መልኩ፣ አንድ ዝግጁገጽታን በ‘ዓቅርብ (render) እንደገና ማቅረቡ እንደ አዲስ መጠይቅ አይቆጠርም፡፡ በዚህ ምክንያትም ብልጪታው በቛሚነት በማንፈልገው ገጽ ላይ ሁሉ የብልጪታ መልእክቱን ማሳየቱን ይቀጥላል። ለምሳሌ:- አንድ ብቁ ያልሆነ የግብዓት መረጃን ብናስረክብ እና ከዚያ በኋላ የመነሻ ገጹ ላይ ጠቅ ብናደርግ፣ ብልጪታው ለሁለተኛ ጊዜ ይታያል (ምስል 8.7)። ይህንን ሳንካ የማስተካከሉ ተግባር ለክፍል 8.1.5 የተያዘ ስራ ይሆናል፡፡

images/figures/flash_persistence
ምስል 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 ላይ የሚታዩትን ቅደም ተከተሎች ለማግኘት አንድ ፈተና ያስፈልገናል፡፡ ለዚሁ ፈተና መሰረታዊ የሆኑት ቅደም ተከተሎች እነዚህ ናቸው፡-

  1. የግብዓት መንገዱን መጎብኘት።
  2. የአዲስ ክፍለጊዜወች ቅጽ በትክክል መቅረቡን ማረጋገጥ።
  3. አንድ ብቁ ያልሆነ የ‘ሰሚአሴቶች (params) ተርታን በክፍለጊዜወች መንገድ ላይ ማስቀመጥ።
  4. አዲሱ የክፍለጊዜወች ቅጽ እንደገና መቅረቡን እና አንድ የብልጪታ መልእክት መታየቱን ማረጋገጥ።
  5. ሌላ ገጽን መጎብኘት (ለምሳሌ የመነሻ ገጽን) እና
  6. የብልጪታ መልእክቱ በተጎበኘው ገጽ ላይ የማይታይ መሆኑን ማረጋገጥ ናቸው፡፡

ከላይ የተጠቀሱትን ቅደም ተከተሎች ተግባራዊ የሚያደርገው አንድ ፈተና በዝርዝር 8.9 ውስጥ ይገኛል፡፡

ዝርዝር 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 ውስጥ ያለውን ፈተና ካከልን በኋላ፣ የግብዓት ፈተናው ቀይመሆን አለበት:-

ዝርዝር 8.10: ቀይ
$ rails test test/integration/teteqamis_gba_test.rb

ይህ የ‘ሬይልስ ፈትን (rails test) ዘዴን እና የፋይሉን ሙሉ መንገድ በመጠቀም፣ አንድ እንኮ የፈተና ፋይልን ብቻ እንዴት ማስኬድ እንደሚቻል ያሳያል።

ዝርዝር 8.9 ላይ ያለውን የወደቀ ፈተና ለማሳለፍ የሚቻልበት መንገድ አሁን ያለውን የ‘ብልጪታ (flash) ዘዴን ለየት ያለ መልክ ባለው የ‘አሁን.ብልጪታ (flash.now) ዘዴ በመተካት ሲሆን፣ ይህም በሚቀርቡ ገጾች ላይ የብልጪታ መልእክቶችን ለማሳየት ተብሎ የተነደፈ ነው፡፡ ከ‘ብልጪታ (flash) ይዞታ በተቃራኒ መልኩ የ‘አሁን.ብልጪታ (flash.now) ዘዴው፣ ልክ አንድ አዲስ ተጨማሪ መጠይቅ ከአሳሹ ሲመጣ ይዞታው ሁሉ ይጠፋል፣ ይህንንም በዝርዝር 8.9 ላይ ፈትነን ያረጋገጥነው ባህሪ ነው፡፡ በአዲሱ ብልጪታ ተተክቶ የተስተካከላው የአፕልኬሽኑ ኮድ በዝርዝር 8.11 ውስጥ ይታያል፡፡

ዝርዝር 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

ከዚያ ሁለቱም ማለት የግብዓት የውህደት ፈተናው እና ሙሉው የፈተና ስብስቡ አረንጓዴመሆናቸውን ማረጋገጥ እንችላለን፡-

ዝርዝር 8.12: አረንጓዴ
$ rails test test/integration/teteqamis_gba_test.rb
$ rails test

መልመጃዎች

የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።

የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡

  1. ክፍል 8.1.4 ላይ፣ የተዘረዘሩት ቅደም ተከተሎች በትክክል እንደሚሰሩ አሳሻችሁን በመጠቀም አረጋግጡ፡፡ ይህ ማለት ከነበራችሁበት ገጽ ወደ ሌላ ገጽ ለመሸጋገር ሌላው ገጽ ላይ ጠቅ በምታደርጉበት ጊዜ፣ የብልጪታ መልእክቱ መጥፋት ይኖርበታል ማለት ነው፡፡

8.2 ግብዓት

አሁን የኛ የግብዓት ቅጽ ብቁ ያልሆኑ ርካቦቶችን (ማስረከቦችን) ማስተናገድ ስለሚችል፤ ቀጣዩ ሂደት ብቁ ርካቦትን በትክክል በማስተናገድ ተጠቃሚን ማስገባት ነው። በዚህ ክፍል ውስጥ፣ አሳሹ ሲዘጋ ጊዜው በራስሰር በሚቃጠል በአንድ ጊዜያዊ የክፍለጊዜ ብስኩት ተጠቃሚው እንዲገባ እናደርጋለን። በክፍል 9.1 ላይ አሳሹ ከተዘጋ በኋላም እንኳ የሚቆዩ ክፍለጊዜወችን እናክላለን።

ክፍለጊዜወችን መተግበሩ በበርካታ መቆጣጠሪያወች እና ትይታዎች ላይ ጥቅም ላይ የሚውሉ በርካታ የሚዛመዱ ተግባሮችን መበየንን ያሳትፋል። ሩቢ እንደዚህ ያሉ ተግባሮችን በአንድ ቦታ ለመሰብሰብ አንድ ክፍለክፍል (module) የተባለ ቦታ እንደሚሰጥ በክፍል 4.2.4 ላይ እንደተመለከትን ታስታውሱ ይሆናል፡፡ ለምቾትም፣ የክፍለጊዜወች መቆጣጠሪያን በማመንጨት ወቅት አንድ የክፍለጊዜ ረጅ ክፍለክፍል በራስሰር መንጪቷል (ክፍል 8.1.1)፡፡ በተጨማሪም፣ እንደዚህ ያሉ ረጅወች በሬይልስ ትይታዎች ውስጥ በራስሰር ይካተታሉ፤ ክፍለክፍሉን በሁሉም መቆጣጠሪያወች መሰረተ ክፍል ውስጥ (ማለት የአፕልኬሽን መቆጣጠሪያ ውስጥ) በማካተት በኛ መቆጣጠሪያዎች ውስጥም እንዲገኙ ለማድረግ ዝግጅት እናደርጋለን (ዝርዝር 8.13)።2

ዝርዝር 8.13: የክፍለጊዜ ረጅ ክፍለክፍሉን በአፕልኬሽን መቆጣጠሪያው ውስጥ ማካተት። app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  include SessionsHelper
end

ሁሉ ውቅረት ተጠናቋል፤ አሁን ተጠቃሚዎችን ለማስገባት የሚያስችለንን ኮድ ለመጻፍ ዝግጁ ነን፡፡

8.2.1 የ‘ግባ ዘዴ

በሬይልስ በተበየነው የ‘ክፍለጊዜ (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) የተባለ ዘዴን እንበይናለን፡፡

ዝርዝር 8.14: የ‘ግባ (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 ውስጥ ይታያል፡፡

ዝርዝር 8.15: አንድ ተጠቃሚን ማስገባት። 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 ውስጥ ወደ አሁንተጠቃሚው መገለጫ የሚወስደውን ዓ.አ.ሃ.አን እና የግብዓት አገናኞቹን ወደ አፕልኬሽኑ ገጽታ እናመጣቸዋለን።

መልመጃዎች

የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።

የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡

  1. ሁሉን መስፈርቶች ባሟላ አንድ ተጠቃሚ ከገባችሁ በኋላ፣ አሳሻችሁ ላይ ያሉትን ብስኩቶች መርምሩ፡፡ ያገኛችሁት የክፍለጊዜ ይዘት ዋጋ ምንድን ነው? ጠቃሚ ምክር:- የዚህን መልስ በቀላሉ ለማግኘት፣ አሳሻችሁ ላይ የሚገኙ ብስኩቶችን እንዴት አግኝታችሁ ይዞታቸውን ማየት የማትችሉ ከሆነ፣ ጎግል ላይ ጎልጉሉት (ሳጥን 1.2)፡፡
  2. በብስኩቱ ውስጥ የሚገኘው፣ የ‘ይቃጠላል (Expires) ባሕሪ ዋጋ ምንድ ነው?

8.2.2 የአሁንተጠቃሚ

የተጠቃሚውን መታወቂያ በጥብቅ ጊዜያዊ ክፍለጊዜ ካስቀመጥን በኋላ፣ አሁን ተጠቃሚውን ተከታታይ ገጾች ላይ ፈልገን ለማግኘት የምንችልበት አቋም ላይ እንገኛለን፣ ይህንን ተግባራዊ ለማድረግም ከክፍለጊዜ መታወቂያው ጋር የሚዛመደውን ተጠቃሚ መፈለግ ስላለብን አንድ ዓሁን_ተጠቃሚ (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)፡፡

ሳጥን 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 ላይ ስንደርስ እናስወግደዋለን።)

ዝርዝር 8.16: በክፍለጊዜው ውስጥ የአሁንተጠቃሚን መፈለግ። 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) ዘዴ ጋር፣ አሁን በተጠቃሚው የግብዓት ሁኔታ ላይ በመመርኮዝ በአፕልኬሽናችን ላይ ለውጦችን የምናደርግበት አቋም ላይ ደርሰናል፡፡

መልመጃዎች

የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።

የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡

  1. ተጠቃሚ.ፈልግበ መታወቂያ‘ን (Teteqami.find_by(id: ...)) በሬይልስ ሰሌዳ ላይ በመጠቀም፣ ተዛማጅ ተጠቃሚ በማይኖርበት ጊዜ ምንምን (nil) እንደሚመልስ አረጋግጡ፡፡
  2. ዝርዝር 8.17 ውስጥ የተዘረዘረውን ቅደም ተከተል በመከተል፣ መጀመሪያ በሬይልስ ሰሌዳ ላይ አንድ :ተጠቃሚ_መታወቂያ (:teteqami_id) የተባለ ቁልፍ የያዘ ክፍለጊዜ (session) የተባለ አንድ ተርታን ፍጠሩ። ከዚያ ቅደም ተከተሉን አንድ ባንድ በመከተል የ ||= ስሌቱ እንደተፈለገው መስራቱን አረጋግጡ፡፡
ዝርዝር 8.17: የ‘ክፍለጊዜ (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.2.4 የገጽታ ለውጦችን መፈተን

ስኬታማ ለሆነ ግብዓት አፕልኬሽኑ በትክክል እንደሚሰራ በእጃችን ካረጋገጥን በኋላ፣ ዝም ብለን ከመቀጠላችን በፊት፣ ይህንን ባህሪ ለማረጋገጥ እና ምልሰቶችን ለመያዝ አንድ የውህደት ፈተናን እንጽፋለን፡፡ በዝርዝር 8.9 ውስጥ በሚገኘው ፈተና ላይ ግንባታውን እንቀጥል እና የሚከተሉት ድርጊቶች ቅደም ተከተልን ለማረጋገጥ ተከታታይ ሂደቶችን እንጽፋለን:-

  1. የግባት መንገዱን መጎብኘት።
  2. በክፍለጊዜወች መንገድ ላይ ብቁ መረጃን ማስቀመጥ።
  3. የግባት አገናኙ መጥፋቱን ማረጋገጥ።
  4. የውጣት አገናኙ መታየቱን ማረጋገጥ።
  5. የመገለጫ አገናኙ መታየቱን ማረጋገጥ።

እነዚህን ለውጦች ለማየት፣ ፈተናችን፣ ከዚህ በፊት እንደ ተመዝገበ ተጠቃሚ ሆኖ፣ እንደ አዲስ የሚገባ አንድ ተጠቃሚን ይፈልጋል፤ ይህ ማለት እንዲህ ያለ አንድ ተጠቃሚ ከድሮው በውሂበጎታው ውስጥ ግዴታ መኖር አለበት ማለት ነው፡፡ ይህንን ለማድረግ ነባሪው የሬይልስ አሰራር እቃወችን መጠቀም ነው፤ ይህም ሬይልስ ወደ ፈተና ውሂበጎታ የሚጫኑ መረጃዎችን የሚያደራጅበት አንዱ መንገድ ነው፡፡ የኤመልእክት ልዩነት ፈተናወቻችን ያልፉ ዘንድ፣ (ዝርዝር 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 ውስጥ ይታያል፡፡

ዝርዝር 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 ላይ እንደሚታየው፣ ለአንድ ብቁ ተጠቃሚ አንድ የተጠቃሚ እቃን ለመፍጠር ዝግጁ ነን፡፡

ዝርዝር 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 ላይ እንደሚታየው፤ ከላይ ባለው የእቃ ተጠቃሚው ጋር፣ በዚህ ክፍል መጀመሪያ ላይ የተዘረዘሩትን ቅደም ተከተሎች ወደ ኮድ በመለወጥ አሁን ለገጽታው አገናኞች አንድ ፈተናን መጻፍ እንችላለን፡፡

ዝርዝር 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) ስልት ጋር አነጻጽሩ፡፡)

የአፕልኬሽን ኮዱ ከድሮውም ይሰራ ስለነበረ፣ ይህ ፈተና ያለምንም ጥርጥር አረንጓዴመሆን አለበት:-

ዝርዝር 8.28: አረንጓዴ
$ rails test test/integration/teteqamis_gba_test.rb

መልመጃዎች

የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።

የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡

  1. ዝርዝር 8.15 ውስጥ ያለው ኮድ ላይ፣ ስምንተኛው መስመር ላይ፣ ልክ በዝርዝር 8.29 እንደተመለከተው፣ if teteqami ከሚለው በኋላ አስተያየት በማድረግ፤ ኤመልእክቱን እና መሕለፈቃሉን ተጠቅመን ተጠቃሚውን ብናረጋግጥም እንኳን ፈተናው ግን እንደሚያልፍ አረጋግጡ፡፡ ለምን ፈተናው ያልፋል? የሚል ጥያቄ ሊነሳ ይችላል፤ ምክንያቱ በዝርዝር 8.9 ላይ የሰፈረው ፈተና አንድ ትክክለኛ የሆነ የተጠቃሚ ኤመልእክትን ሳይሆን፤ አንድ ትክክል ያልሆነ የተጠቃሚ መሕለፈቃልን ብቻ ስለሚፈትን ነው፡፡ በዝርዝር 8.30 ላይ እንደተመለከተው፣ በተጠቃሚዎች የመግቢያ ፈተና ላይ፣ አንድ ብቁ የኤመልእክትን በማከል ይህን አስፈሪ ቀዳዳ ድፈኑ፡፡ አሁን ባለንበት ደረጃ ላይ ፈተናው ቀይመሆኑን ካረጋገጣችሁ በኋላ፣ ከዚያ ፈተናውን አረንጓዴለማድረግ ካሁን በፊት ያደረጋችሁትን አስተያየት ካለበት ቦታ አስወግዱ። (ይህ ፈተና በጣም አስፈላጊ ስለሆነ፣ በክፍል 8.3 ላይ ወደ ዋናው ኮድ እናክለዋለን።)
  2. ዝርዝር 8.15 ውስጥ፣ ስምንተኛው መስመር ላይ፣ ያለውን የቡልየን ፈተናን ለማቃለል በዝርዝር 8.3116 ውስጥ ስምንተኛው መስመር ላይ እንደሚታየው፣ “ደህንነቱ የተጠበቀ የአሰሳ (safe navigation)” ስሌትን &. ተጠቀሙ። ይህ የሩቢ ገጸባህሪ በ‘ቁስ && (obj &&) እና በ‘ቁስ.ዘዴ (obj.method) ውስጥ ያለውን ተመሳሳይ ጥለት እንደዚህ obj&.method አድርገን እጥር ምጥን እንድናደርገው ያስችለናል፡፡ በዝርዝር 8.30 ውስጥ ያሉት ፈተናወች ከተደረገው ለውጥ በኋላም ማለፋቸውን አረጋግጡ፡፡
ዝርዝር 8.29: የማረጋገጫ ኮዱ አስተያየት ተደርጎበታል፣ ፈተናወቹ ግን አሁንም አረንጓዴናቸው። 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
ዝርዝር 8.30: ብቁ የተጠቃሚ ኤመልእክትን ብቃት ከሌለው የመሕለፈቃል ጋር መፈተን። 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
ዝርዝር 8.31: የመግቢያ ኮዱን ለማቃለል፣ “ደህንነቱ የተጠበቀ የአሰሳ (safe navigation)” ስሌትን &. መጠቀም። app/controllers/sessions_controller.rb
class SessionsController < ApplicationController

  def new
  end

  def create
    teteqami = Teteqami.find_by(emelekt: params[:session][:emelekt].downcase)
    if teteqami&.authenticate(params[:session][:password])
      reset_session
      gba teteqami
      redirect_to teteqami
    else
      flash.now[:danger] = 'ልክ ያልሆነ የኤመልእክት/የይለፍ ቃል ጥምረት'
      render 'new'
    end
  end

  def destroy
  end
end

8.2.5 ልክ እንደተዘገቡ ማስግባት።

ምንም እንኳን የማረጋገጫ ስርዓታችን አሁን እየሰራ ቢሆንም፤ አዲስ የተመዘገቡ ተጠቃሚዎች በነባሪነት መግባት ስለማይችሉ ግራ ሊጋቡ ይችላሉ፤ ተጠቃሚዎች ከተመዘገቡ በኋላ ወዲያውኑ እንዲገቡ ማስገደዱ እንግዳ ነገር ስለሆነ፣ የምዝገባው ሂደት አካል ይሆን ዘንድ፣ አዲስ ተጠቃሚዎች ልክ እንደተመዘገቡ በራስሰር እናስገባቸዋለን። ይህንን ባህሪ ለማስተካከል ማድረግ የሚኖርብን ነገር ቢኖር፣ በተጠቃሚዎች መቆጣጠሪያ የ‘ፍጠር (create) ተግባር ውስጥ አንድ የ‘ግባ (gba) ጥሪን ማከል ብቻ ነው፡፡17ክፍል 8.2.1 ውስጥ የተወያየንበትን የክፍለጊዜ ጥገና ጥቃቶችን ለመከላከል፣ (ልክ በዝርዝር 8.15 ላይ እንዳደረግነው) ከማስገባታችን በፊት ወዲያውኑ አንድ የ‘ክፍለጊዜ_እንደገናአስጀምር (reset_session) ጥሪንም አክለናል። ውጤቱ በዝርዝር 8.32 ውስጥ ይታያል፡፡

ዝርዝር 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 ላይ ያለውን መሰናክል አያልፍም ስለሆነም፤ ይልቁንስ በሁሉም ጉዳዮች ላይ የሚሰራ አንድ ፈተና ላይ ያተኮረ ዘዴን እንበይናለን፡፡)

ዝርዝር 8.33: በፈተና ውስጥ የተጠቃሚ የግባት ሁኔታን የሚፈትን አንድ የቡልየን ዘዴ። 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 ላይ የተመለከተውን አንድ መስመር ኮድ በመጠቀም፣ ተጠቃሚው ከተመዝገበ በኋላ እንደገባ ማረጋገጥ እንችላለን፡፡

ዝርዝር 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

በዚህ ጊዜ የፈተና ስብስቡ አረንጓዴመሆን አለበት:-

ዝርዝር 8.35: አረንጓዴ
$ rails test

መልመጃዎች

የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።

የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡

  1. ዝርዝር 8.32 ውስጥ፣ የ‘ግባ (gba) ዘዴ ፊት ላይ አስተያየት ብታደርጉ የፈተና ስብስቡ ምን ይሆናል? አረንጓዴ ወይስ ቀይ ?
  2. አንድ የጽሑፍ አርታኢን በመጠቀም፣ በዝርዝር 8.32 ላይ ያለውን ኮድ አስተያየት በማድረግ እና ባለማድረግ ፈተናው ከ ቀይ ወደ አረንጓዴአረንጓዴወደ ቀይ እንደሚቀያየር አረጋግጡ፡፡ (በመቀያየር ወቅት ፋይሉን ማስቀመጥ ይፈለግባችኋል።)

8.3 መውጣት

ክፍል 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) ዘዴንም እዛው እናስቀምጠዋለን፡፡

ዝርዝር 8.36: የ‘ውጣ (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) ተግባር ውስጥ እንጠቀምበት ዘንድ፣ እሱን እዛው ውስጥ ማስቀመጥ እንችላለን፡፡

ዝርዝር 8.37: አንድ ክፍለጊዜን ማጥፋት (የተጠቃሚ መውጣት)። 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 ውስጥ ይታያሉ፡፡

ዝርዝር 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) ተግባር ጋር፣ የምዝገባ/የመግቢያ/የመውጫ የመጀመሪያ ስራ በድል ተጠናቋል፤ እና የፈተና ስብስቡም አረንጓዴመሆን አለበት፡-

ዝርዝር 8.39: አረንጓዴ
$ rails test

መልመጃዎች

የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።

የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡

  1. አሳሻችሁን በመጠቀም፣ የ “ይውጡ” አገናኝ ጠቅ በሚደረግበት ጊዜ፣ የጣቢያው ገጽታ ትክክለኛወቹን ለውጦች እንደሚያደርግ አረጋግጡ፡፡ አሳሻችሁን በመጠቀም፣ ያረጋገጣችኋቸው ለውጦች በዝርዝር 8.38 መጨረሻ ላይ ካሉት ሶስት ፈተናወች ጋር ያላቸው ዝምድና ምንድን ነው?
  2. የጣቢያውን ብስኩቶች በመፈተሽ፣ ከጣቢያው ከወጣችሁ በኋላ ክፍለጊዜው በትክክል እንደተወገደ አረጋግጡ፡፡

8.4 ማጠቃለያ

እድሜ ለዚህ ምዕራፍ፣ የማሳያ አፕልኬሽናችን አንድ ሙሉ በሙሉ የሚሰራ የመግቢያ እና የማረጋገጫ ስርዓት አለው፡፡ በሚቀጥለው ምዕራፍ ላይ፣ ተጠቃሚዎችን ከአንድ ነጠላ የአሳሽ ክፍለ ጊዜ በላይ ረዘም ላለ ጊዜ የማስታወስ ችሎታን በማከል አፕልኬሽናችንን ወደላቀ ደረጃ እናሸጋግረዋለን።

ከመቀጠላችሁ በፊት፣ ለውጦቻችሁን ወደ ዋና ቅርንጫፍ አዋህዱ:-

$ rails test
$ git add -A
$ git commit -m "መሰረታዊ መግቢያን መተግብር"
$ git checkout main
$ git merge መሰረታዊ-መግቢያ

በመቀጠል ወደ ሩቅ ማስቀመጫ ግፉት:-

$ rails test
$ git push

መጨረሻ፣ እንደተለመደው ወደ ሃረኩ አሰማሩ:-

$ git push heroku

8.4.1 በዚህ ምዕራፍ ውስጥ የተማርናቸው ነገሮች:-

  • ሬይልስ በ‘ክፍለጊዜ (session) ዘዴ በኩል ጊዜያዊ ብስኩቶችን በመጠቀም፣ ከአንድ ገጽ እስከ ሚቀጥለው ገጽ ድረስ ሁኔታን ጠብቆ ማቆየት እንደሚችል፣
  • የመግቢያ ቅጹ አንድን ተጠቃሚ ለማስገባት፤ አንድ አዲስ ክፍለጊዜን ለመፍጠር የተነደፈ መሆኑን፣
  • የ‘አሁን.ብልጪታ (flash.now) ዘዴ በቀረቡ ገጾች ላይ ለብልጪታ መልእክቶች ጥቅም ላይ እንደሚውል፣
  • በማረም ወቅት ፈተና-መሬ ብልጸጋ ሳንካውን በአንድ ፈተና ውስጥ እንደገና በማምረት ጠቃሚ መሆኑን፣
  • የ‘ክፍለጊዜ (session) ዘዴን በመጠቀም፣ አንድ ጊዜያዊ የሆነ ክፍለጊዜን ለመፍጠር፣ በአሳሹ ላይ የአንድ ተጠቃሚ-መታወቂያን በጥብቅ ማስቀመጥ እንደምንችል፣
  • በግብዓት ሁኔታ ላይ መሰረት በማድረግ በገጽታው ላይ ያሉ ገጸባህሪያቶችን ማለት አገናኞችን መለወጥ እንደምንችል እና
  • የውህደት ፈተናዎች ትክክለኛ ማዘዋወሪያወችን፣ የውሂበጎታ ማዘመኖችን እና በገጽታው ላይ የተደረጉ ተገቢ ለውጦችን ሊያረጋግጡ እንደሚችሉ ተምረናል።
1. አንዳንድ አሳሾች እንደዚህ ያሉ ክፍለጊዜወችን እነበሩበት እንዲመለሱ “ካቆምክበት ቀጥል” (“continue where you left off”) በሚለው በይነገጽ አማካኝነት አንድ አማራጪን ያቀርባሉ፤ ሬይልስ ግን በዚህ በይነገጽ ላይ ምንም ዓይነት ሃይል የለውም። በእንደዚህ ዓይነት ሁኔታዎች ላይ የክፍለጊዜው ብስኩት አፕልኬሽኑን ዘግታችሁ ከወጣችሁም በኋላም እንኳን ሊቆይ ይችላል።
2. ክፍለክፍል ንጹህ የሩቢ መንገድን ስለሚያካትት እና ስለሚያገናኝ ይህንን ብልሃት እወዳለሁ። ነገር ግን ሬይልስ 4 ለዚሁ አላማ ሊያገለግል የሚችል አንድ ከንሰርንስ (Concerns) ተብሎ የሚጠራ ስልትን አስተዋውቋል፡፡ ኮንሰርን እንዴት እንደሚሰራ ለማወቅ “እንዴት ከንሰርንን በሬይልስ ውስጥ መጠቀም ይቻላል ” የሚለውን አገናኝ ጠቅ በማድረግ ስለሱ መማር ትችላላችሁ።
3.ዝርዝር 8.13 ውስጥ በክፍለክፍሉ መካተት ምክንያት የ‘ግባ (gba) ዘዴው በክፍለጊዜ መቆጣጠሪያ ውስጥ ይገኛል፡፡
4. ከአንዱ ዘዴ ጥሪ እስከ ቀጣዩ ያለውን የተለዋዋጪ ምደባ የማስታወስ አሰራር አስታውሴ (memoization) በመባል ይታወቃል። (ይህ ቴክኒካዊ ቃል መሆኑን ልብ ልትሉት ይገባል፣ ከዚህ በፊት በነበረው የመጽሐፉ እትም ላይ፤ የመጽሃፉ አርታኢ ባጋጣሚ “ማስታወስ (memorization)” የሚለውን ቃል ለመጻፍ ተብሎ የተደረገ እንደመሰለው ሁሉ፣ እናንተንም እንደዛ እንዳይመስላችሁ።)
5. ምስሉ በ 2016-06-03 ከ https://www.flickr.com/photos/elevy/14730820387 የተወሰደ ነው፡፡ የቅጅ መብት © 2014 በኤልያስ ሌቢ እና የጋራ የፈጠራ አጠቃላይ ዋለዮ 2.0 ፈቃድ መሰረት ስእሉ ላይ ለውጥ አልተደረገም።
6. አሳሾች የሠርዝ (DELETE) መጠይቅን መስጠት አይችሉም፣ ሬይልስ ግን ጃቫስክሪፕትን በመጠቀም ይህንኑ ተግባር ያስኬዳል፡፡
7. የበለጠ መረጃ ለማግኘት የቡትስትራፕ አካላት ገጽን ተመልከቱ፡፡
8. ይህ እንዲሰራ ድርአሳሻችሁን እንደገና ማስጀመር ሊኖርባችሁ ይችላል (ሳጥን 1.2)።
9. የደመና ቅ.ማ.አን እየተጠቀማችሁ ከሆነ አንድ ቅ.ማ.አን በማስኬድ ላይ ያለ አሳሽን ላለመዝጋት እና የግብዓት ባህሪውን ለመፈተን አንድ የተለየ አሳሽን እንድትጠቀሙ ሃሳቤን እለግሳለሁ።
10. ከነዚህ ለውጦች መካከል በርካቶቹ፣ የሬይልስ ስልጠና አንባቢ ከሆነው፣ በክቡር ክሬግ ዘይሴ ሃሳብ ወይም አነሳሽነት ላይ የተመሰረቱ ናቸው፡፡
11. የጎግል ክሮም የድር መመርመሪያም እንዲህ ያለ ተመሳሳይ ገጸባህሪ አለው፡፡ በዚህ ጣቢያ በቅ.ቋ እና በገጽታ ላይ መሰረታዊ እውቀትን ለማግኘት የሚያስፈልገውን ተማር ውስጥ “የተንቀሳቃሽ የእይታማረፊያ” የሚለውን ሌላ አማራጪንም መመልከት ትችላላችሁ፡፡
12. ለማንኛውም መሳሪያዎች ምጥጥነ ገጽታውን ከቁም አቀማመጥ ወደ መልክዓ-ምድራዊ አቀማመጥ ለመለወጥ በቀላሉ በተጓዳኙ አዶ ላይ ሁለቴ ጠቅ ያድርጉ። ድሮ በቅ.ቋ እና በገጽታ ላይ መሰረታዊ እውቀትን ለማግኘት የሚያስፈልገውን ተማርየተባለውን ስልጠና በማዘጋጀት ላይ በነበረበት ጊዜ፣ እኔ እና ረዳት ደራሲየ ሊ ዶናሆ ይህንን ለማወቅ በጣም ረጅም ጊዜ ወስዶብን ነበረ፡፡
13. ስለዚህ የበለጠ መረጃ ለማግኘት በዚህ ጣቢያ በቅ.ቋ እና በገጽታ ላይ መሰረታዊ እውቀትን ለማግኘት የሚያስፈልገውን ተማር ውስጥ “የተንቀሳቃሽ የእይታማረፊያ” የሚለውን ተመልከቱ፡፡
14. ክቡር ክሬግ ዜይስ ለሰጡት አስደናቂ የበጎ ፈቃደኝነት አስተዋጻኦ በድጋሚ አመሰግናለሁ። ይህንን ነገር እራሴ አላውቀውም ነበር፡፡
15. ለለርንኢነፍ መስራች እና የ በቅ.ቋ እና በገጽታ ላይ መሰረታዊ እውቀትን ለማግኘት የሚያስፈልገውን ተማር ስልጠና ተባባሪ ደራሲ ለሆነው ክቡር ሊ ዶናሆ ስላደረገው እርዳታ ሁሉ በጣም አመሰግናለሁ፡፡
16. የተከበሩ አንባቢ አቪቭ ሌቪንስኪን ይህን ተጨማሪ ሃሳብ ስለሰጡ ከልብ አመሰግናለሁ።
17. እንደ የክፍለጊዜወች መቆጣጠሪያ የ‘ግባ (gba) ዘዴው በዝርዝር 8.13 ክፍለክፍል ውስጥ ስለተካተተ በተጠቃሚዎች መቆጣጠሪያ ላይም እንደዚሁ ይገኛል።
18. ለምሳሌ፣ በክፍለጊዜ ረጅው ውስጥ ዋናውን የ‘ግባ (gba) ዘዴን በድንገት ከሰረዝኩት በኋላም እንኳን፣ አንድ ጊዜ አረንጓዴየፈተና ስብስብን አግኝቼ አውቃለሁ። ይህ የሆነበት ምክንያት አፕልኬሽኑ ሙሉ በሙሉ ባይሰራም እንኳን፣ ፈተናወቹ ግን በተመሳሳይ ስም የተበየነውን የፈተና ረጅ በመጠቀም ይሰሩ ስለነበር ነው። ልክ እንደ ገብ_ቷልን? (geb_tual?) በዝርዝር 9.24 ውስጥ የፈተና ረጅውን ግባ_እንደ (gba_ende) የተባለ ዘዴን በመበየን ይህንን ችግር እናስወግዳለን፡፡
19. አንዳንድ አሳሾች አንድ ክፍለጊዜን በራስሰር የሚያድስ “ያቆምኩበት ቦታን አስታውስልኝ” የተባለ አንድ ገጸባህሪን ያቀርባሉ፤ ስለሆነም ከመውጣታችሁ በፊት ማንኛውንም ዓይነት ገጸባህሪ ማቦዘናችሁን አረጋግጡ።
20. የ‘@ዓሁን_ተጠቃሚ (@ahun_teteqami) ቅርፀ ተለዋዋጪን የ‘ምንም (nil) ዋጋን መመደቡ ከ‘አጥፋ (destroy) ተግባር በፊት ከሆነ እና ምንም (nil) ከሆነ በኋላ ወድያውኑ የማይዟዟር ከሆነ ችግር ያስከትላል። ይህ ሊሆን የማይችል የክስተት ጥምረት ነው፣ አሁን በዚህ አፕልኬሽን ላይ የቅርፀ ተለዋዋጩን አንድ የ‘ምንም (nil) ዋጋን መመደቡ አስፈላጊ አይደለም፣ ነገር ግን ከጥበቃ ጋር በተዛመደ መልኩ የተሟላ ይሆን ዘንድ ጨምሬዋለሁ።