በምዕራፍ 5 ውስጥ አዲስ ተጠቃሚዎችን ለመፍጠር አንድ የተቆረጠ ገጽን በመፍጠር አጠናቀን ነበር (ምዕራፍ 5.4)። በሚቀጥሉት ስድስት ምዕራፎች ውስጥ፣ ለዚህ ጨቅላ የምዝገባ ገጽ የተገባውን ቃል ኪዳን እናሟላለን፡፡ በዚህ ምዕራፍ ውስጥ የተጠቃሚዎች ውሂብ የምናስቀምጥበትን መንገድ እና ለጣቢያችን ተጠቃሚዎች አንድ የውሂብ ቅርጽን ለመቅረጽ የመጀመሪያውን ወሳኝ እርምጃ እንወስዳለን፡፡ በምዕራፍ 7 ውስጥ ተጠቃሚዎች ለጣቢያችን የሚመዘገቡበትን እና አንድ የመገለጫ ገጽ የሚፈጥሩበትን ችሎታ እንሰጣለን፡፡ አንዴ ተጠቃሚዎች ከተመዘገቡ በኋላ ወደ ጣቢያው እንዲገቡ እና ከጣቢያው እንዲወጡ እናስችላቸዋለን (ምዕራፍ 8 እና ምዕራፍ 9)፣ እና በምዕራፍ 10 (ክፍል 10.2.1) ውስጥ ገጾችን አላግባብ ከሆነ ድርሰት እንዴት እንደምንከላከል እንማራለን፡፡ በመጨረሻም፣ በምዕራፍ 11 እና በምዕራፍ 12 ላይ የመለያ ግባሬወችን (በዚህም አንድ ትክክለኛ የኤመልእክት አድራሻ መኖሩን እናረጋግጣለን) እና የመሕለፈቃል ዳግም ማስጀመርያን እናክላለን፡፡ ከምዕራፍ 6 ጀምሮ እስከ ምዕራፍ 12 ያሉትን ነገሮች በሙሉ አንድ ላይ ማጣመሩ፣ አንድ የሬይልስ አፕልኬሽን የመግቢያ እና የማረጋገጫ ስርዓትን ይገነባል። ሬይልስ የተለያዩ ቀድመው-የተገነቡ የማረጋገጫ መፍትሄዎች እንዳሉት ምናልባት ታውቁ ይሆናል፣ ሳጥን 6.1 ቢያንስ ቢያንስ መጀመሪያ ላይ፣ አንድ የራሳችሁ የሆነ የማስረገጫ ስርዓት እንዲኖር ማድረጉ ለምን የተሻለ ሃሳብ እንደሆነ ያሳያል፡፡
ሁሉም የድር አፕልኬሽኖች ማለት ይቻላል የሆነ ዓይነት የመግቢያ እና የማረጋገጫ ስርዓት ያስፈልጋቸዋል፡፡ በዚህ ምክንያትም አብዛኛዎቹ የድር መዋቅሮች ከአንድ ወይም ከብዙ መደበኛ ቤተኮዶች ላይ ይወሰናሉ፤ እና ሬይልስም ከነሱ የተለየ አይደለም፡፡ በተለይም ዲቫይስ የተባለው እንቁ ለበርካታ የተለያዩ አጠቃቀሞች እንደ አንድ ብቁ መፍትሄ ሆኖ ብቅ ብሏል፣ በዚህ ምክንያትም ሞያዊ-ደረጃ ባላቸው አፕልኬሽኖች ዘንድም የበላይ የሆነ ተመራጪነትን ተቀናጅቷል።
የሆነ ሆኖ፣ እንደ ዲቫይስ ያለ ቤተኮድን ማለት ቅድሞ-ገነብ ስርዓትን እንደዚህ ያለ ስልጠና ላይ መጠቀሙ ስህተት ነው ብዬ አምናለሁ። (በእርግጥ፣ ዲቫይስ ራሱ ይህንን ስልጠና እንድታነቡ ይመክራል።) የተዘጋጁ ስርዓቶች እምቅ እና ምስጢራዊ በሆነ ነገር ውስጥ ያሉ “እንቆቅልሾች” ሊሆኑ ይችላሉ፣ እናም እነዚህ ስርዓቶች የተጠቀሙባቸው የተወሳሰቡ የውሂብ አቀራረጾች፣ ለጀማሪዎች (ወይም የውሂብ አቀራረጽን ጠንቅቀው ለሚያውቁ ልምድ ላላቸው አበልጻጊወች ሳይቀር) እጅግ ግራ የሚያጋቡ ይሆናሉ፡፡ እናም ርዕሰ ጉዳዩን እንደ ማስተማሪያ አድርጎ ለመጠቀም፣ ርዕሰ ጉዳዩን ቀስ በቀስ ማስተዋወቁ አስፈላጊ ይሆናል፡፡ የሚያስደስተው ነገርም፣ ሬይልስ አንድ ለምርት አፕልኬሽን ተስማሚ የሆነ በጣም ጠንካራ የመግቢያ እና የማረጋገጫ ስርዓት ማበልጸጉን ቀስ በቀስ እንድትደርሱበት ማስቻሉ ነው። በዚህ መንገድ፣ በኋላ ላይ በሌሎች የተሰራ አንድ የመግቢያ እና የማረጋገጫ ስርዓት ብትጠቀሙ እንኳን በቀላሉ ልትረዱት እና እንደፈላጋችሁት ልታሻሽሉት በሚያስችላችሁ የተሻለ ደረጃ ላይ ትሆናላችሁ፡፡
የሚቀጥሉት ሶስት ምዕራፎች ዋና አላማ ለጣቢያችን አንድ የምዝገባ ገጽ መስራት ቢሆንም፣ (በምስል 6.1 ላይ በስእላዊ መግለጫው ላይ ለማሳየት እንደተሞከረው) ይህ የምዝገባ ገጽ አሁን የአዲስ ተጠቃሚዎች መረጃን ለመቀበል ግን አያገለግልም፤ በአሁኑ ጊዜ እነዚህን መረጃዎች ለማስቀመጥ የምንችልበት ምንም ቦታ የለንም፡፡ ስለዚህ ተጠቃሚዎችን በመመዝገብ (አባል በማድረግ) ስራ ውስጥ የመጀመሪያው ሂደት መረጃቸውን ለመያዝ እና ለማከማቸት አንድ የውሂብ መዋቅርን መስራት ነው፡፡
በሬይልስ ውስጥ፣ ለአንድ የውሂብ ቅርጸት፣ ነባሪው የውሂብ አወቃቀር እንደምትጠብቁት፣ ቅርጸት (Model) ተብሎ ይጠራል (በክፍል 1.2.3 ውስጥ እንደተመለከተው፣ “ቅ (M)” በ‘ቅ.ተ.መ (MVC) ውስጥ ያለውን የ “ቅ (M)” ተግባርን ያመለክታል)፡፡ ጽናትን ለመቛቛም የሬይልስ መፍትሄ አንድ የውሂበጎታን ለረጅም-ጊዜ የውሂብ ማከማቻ አድርጎ በነባሪነት መጠቀም ሲሆን፤ ከውሂበጎታው ጋር መስተጋብርን ለመፍጠር ደግሞ ንቅ መዝገብ (Active Record)1 የተባለውን ቤተኮድ በነባሪነት ይጠቀማል። ንቅ መዝገብ፣ በተዛማጅ ውሂበጎታወች (Relational Databases) ጥቅም ላይ የዋለውን ቀላል የመጠይቅ ቋንቋን (ቀ.መ.ቋን (SQL))2 ማለት ከውሂበጎታ መረጃዎችን ለመፈለግ የሚያገለግለውን ቋንቋ ሳይጠቀም ቁስን ለመፍጠር፣ ውሂበጎታ ላይ ለማስቀመጥ፣ ለማጥፋት፣ ለማዘመን፣ ውሂብን ከውሂበጎታ ለመፈለግ እና ብዙ ነገሮችን ለማድረግ የሚያገለግሉ ዘዴወች ጋር ይመጣል። በተጨማሪም ሬይልስ የተ.መ.ቋን የውሂብ መበየኛ ቋንቋን (ው.መ.ቋ) (Data Definition Language (DDL)) መማር ሳያስፈልግ፣ የውሂብ ብይኖችን በንጹህ ሩቢ ለመጻፍ የሚያስችል አንድ ፍልሰት (Migration) የተባለ ገጸባህሪ አለው፡፡ በዚህ ምክንያትም ሬይልስ ውሂበጎታው ላይ ስለሚደረገው ነገር በዝርዝር እንዳታውቁ እንቅፋት ይሆንባችኋል ማለት ነው፡፡ ይህ በንዲህ እንዳለ፣ በዚህ መጽሐፍ ውስጥ፣ ቀላል የመጠይቅ ቋንቋ (SQLite) የተባለውን ውሂበጎታ ለብልጸጋ እና ፖስትግሬስተ.መ.ቋ የተባለውን ውሂበጎታ ደግሞ በሃረኩ ላይ ለምርት እንድንጠቀም ብቻ ሳይሆን (ክፍል 1.4)፣ ሬይልስ በሁለቱም ማለት በብልጸጋ እና በምርት አፕልኬሽናችን ውሂበጎታ ውስጥ ውሂብን እንዴት እንደሚያስቀምጥ በጪራሽ ማሰብ እንደለለብን ከወዲሁ እንደመድማለን።
እንደተለመደው፣ ጊትን ለስሪት መቆጣጠሪያ እየተጠቀማችሁ ከሆነ፣ አሁን ለተጠቃሚዎች ቅርጸት አንድ የርእስ ቅርንጫፍን ለማድረግ ጥሩ ጊዜ ይሆናል:-
$ git checkout -b ተጠቃሚዎችን-መቅረጽ
በአንድ ብጁ-ግንብ የ‘ተጠቃሚ (Teteqami
) ክፍል በኩል፣ ከተጠቃሚ ቁሶች ማለት ከ‘ስም (sim
) እና ከ‘ኤመልእክት (emelekt
) ባሕሪወቻቸው ጋር ቀደም ሲል ማለት በክፍል 4.4.5 ቆይታችን ላይ እንደተገጣጠምን ታስታውሱ ይሆናል። ያ ክፍል በወቅቱ ልክ እንደ አንድ ጠቃሚ ምሳሌ ሆኖ አገልግሎ ነበረ፣ ነገር ግን ወሳኙ የመጽናት ባህሪ ይጎድለዋል:- አንድ የተጠቃሚ ቁስ በሬይልስ ሰሌዳ ላይ ስንፈጥር ልክ ከሰሌዳው ስንወጣ የፈጠርነው የተጠቃሚ ቁስ ይጠፋል። በዚህ ክፍል ውስጥ ግባችን እንዲሁ በቀላሉ ለማይጠፉ ተጠቃሚዎች የሚሆን አንድ የተጠቃሚወች ቅርጸትን መፍጠር ነው፡፡
ልክ በክፍል 4.4.5 ላይ ለተጠቃሚዎች ክፍል እንዳደረግነው ሁሉ፣ ከሁለት ባሕሪወች ማለት ከአንድ የ‘ስም (sim
) እና ከአንድ የ‘ኤመልእክት (emelekt
) ባሕሪወች ጋር አንድ ተጠቃሚን በመቀረጽ እንጀምራለን፣ የኋለኛውን ባሕሪ ደግሞ እንደ አንድ ልዩ የተጠቃሚስም3 እንጠቀምበታለን፡፡ (በክፍል 6.3 ውስጥ አንድ ባሕሪ ለመሕለፈቃል እናክላለን።) በዝርዝር 4.17 ውስጥ ይህንንም በሩቢ የ‘ባሕሪ_መዳረሻ (attr_accessor
) ዘዴን በመጠቀም እንዲህ አድርገን ሰርተነው ነበር፡-
class Teteqami
attr_accessor :ስም, :ኤመልእክት
.
.
.
end
በተቃራኒው፣ ተጠቃሚዎችን ለመቅረጽ ሬይልስን በምንጠቀምበት ጊዜ፣ ባሕሪያቸውን በግልጽ መለየት አያስፈልገንም። ሬይልስ ከላይ ባጪሩ እንደተመለከተው፣ ውሂቦችን ለማከማቸት አንድ ተዛማጅ ውሂበጎታን በነባሪነት ይጠቀማል፣ ይህም እያንዳንዱ ረድፍ የውሂብ ባሕሪወች አምዶች ያሉበት፣ በውሂብ ረድፎች የተዋቀሩ ሰንጠረዦችን ያቀፈ ነው። ለምሳሌ:- ተጠቃሚወችን እስከ ስማቸው እና የኤመልእክት አድራሻቸው ውሂበጎታ ላይ ለማስቀመጥ ብንፈልግ፣ አንድ ተጠቃሚዎች (teteqamis
) የተባለ ሰንጠረዥን ስም (sim
) እና ኤመልእክት (emelekt
) ከተባሉ አምዶች ጋር እንፈጥራለን (አንድ ረድፍ ከአንድ ተጠቃሚ ጋር የተጎዳኘ ይሆናል)፡፡ የዚህ ሰንጠረዥ ምሳሌ በምስል 6.2 ውስጥ በምስል 6.3 ላይ ከተመለከተው የውሂብ ቅርጸት ጋር ይዛመዳል፡፡ (ምስል 6.3 ላይ ያለው ንድፍ፣ አጠር ያለ ንድፍ ብቻ ነው፣ ሙሉው የውሂቡ ቅርጸት ግን በምስል 6.4 ላይ ይታያል፡፡) አምዶቹን ስም (sim
) እና ኤመልእክት (emelekt
) ብለን በመሰየም፣ ንቅ መዝገብ የተጠቃሚ ቁስ ባሕሪወቹን እራሱ እንዲለይ እንተውለታለን።
በዝርዝር 5.38 ላይ አንድ የተጠቃሚወች መቆጣጠሪያን (ከአንድ አዲስ (new
) ተግባር ጋር) በሚከተለው ትእዛዝ እንደፈጠርን ታስታውሱ ይሆናል፡-
$ rails generate controller Teteqamis new
አንድ ቅርጸትን ለመፍጠር ተመሳሳዩ ትእዛዝ ደግሞ የ‘ቅርጸት-አመንጪ (generate model
) ትእዛዝ ነው፣ በዝርዝር 6.1 ላይ እንደሚታየው፣ ይህንን ትእዛዝ አንድ የተጠቃሚ ቅርጸትን ከ‘ስም (sim
) እና ከ‘ኤመልእክት (emelekt
) ባሕሪወች ጋር ለማመንጨት ልንጠቀምበት እንችላለን፡፡
$ rails generate model Teteqami sim:string emelekt:string
invoke active_record
create db/migrate/20201105235800_create_teteqamis.rb
create app/models/teteqami.rb
invoke test_unit
create test/models/teteqami_test.rb
create test/fixtures/teteqamis.yml
(በደንቡ መሰረት የመቆጣጠሪያ ስሞች በድርብ ስም ሲጠሩ፣ የቅርጸት ስሞች ደግሞ በአንጻሩ በነጠላ ስማቸው ይጠራሉ፤ ስለዚህ የተጠቃሚ መቆጣጠሪያ አንድ የ‘ተጠቃሚወች (Teteqamis) መቆጣጠሪያ ተብሎ ሲሰየም፣ የተጠቃሚ ቅርጸት ደግሞ አንድ የ‘ተጠቃሚ (Teteqami) ቅርጸት ተብሎ ይሰየማል ማለት ነው፡፡ ይህንንም በደንብ ልናጤነው ይገባል።) የምንፈልጋቸው ሁለት ባሕሪወች ምን ዓይነት መሆን እንዳለባቸው (ማለት በዚህ ሁኔታ ላይ የውሂብ ምርጫችን ሃረግ (string
) ነው) ከሁለት አማራጪ ሰሚአሴቶች ማለት ስም:ሃረግ (sim:string
) እና ኤመልእክት:ሃረግ (emelekt:string
) የተባሉ ሰሚአሴቶችን በማሳለፍ ሬይልስ ይህንን ትእዛዝ እንዲፈጽም እንነግረዋለን፡፡ ይህንን በዝርዝር 3.7 እና በዝርዝር 5.38 ውስጥ የተግባር ስሞችን ከማካተት ጋር አነጻጽሩት፡፡
በዝርዝር 6.1 ውስጥ የ‘አመንጪ (generate
) ትእዛዝ ከሚያስገኛቸው ውጤቶች ውስጥ አንዱ፣ አንድ ፍልሰት (Migration) የተባለ አዲስ ፋይል ነው፡፡ ፍልሰቶች የውሂበጎታ አወቃቀሩን አከታትሎ ለመቀየር አንድ መንገድን ይሰጣሉ፣ ስለሆነም የውሂብ ቅዳችን ከተለወጡ መስፈርቶች ጋር እንዲስማማ ያደርጋሉ፡፡ በዝርዝር 6.2 ላይ እንደሚታየው፣ በተጠቃሚ ቅርጸቱ ሁኔታ ላይ ብንመለከት፣ ፍልሰቱ በቅርጸት ማመንጫ ትእዛዙ በራስሰር የተፈጠረ ነው፤ እሱም ከሁለት ማለት ከ‘ስም (sim
) እና ከ‘ኤመልእክት (emelekt
) አምዶች ጋር አንድ ተጠቃሚዎች (teteqamis
) የተባለ ሰንጠረዥን ይፈጥራል። (ፍልሰትን በመጠቀም አንድ የውሂበጎታ ሰንጠረዥ ከባዶ ተነስቶ እንዴት እንደሚሰራ ከክፍል 6.2.5 ጀምረን እንመለከታለን፡፡)
teteqamis
) ሰንጠረዥን ለመፍጠር)፡፡ db/migrate/[ማህተመጊዜ]_create_teteqamis.rb
class CreateTeteqamis < ActiveRecord::Migration[6.0]
def change
create_table :teteqamis do |t|
t.string :sim
t.string :emelekt
t.timestamps
end
end
end
ፍልሰቱ በመነጨበት ጊዜ ላይ በመመርኮዝ፣ የፍልሰቱ ፋይል ስም ከአንድ ማህተመጊዜ ቅድመቅጥያ ጋር ተያይዞ የተቀመጠ መሆኑን ልብ በሉ። ካሁን በፊት በነበረው አሰራር ላይ የፍልሰት ፋይል ስሞች በተከታታይ ሙሉ ቁጥሮች ቅድመቅጥያ ይሰየም ነበር። ይህም የበርካታ አበልጻጊወች የፍልሰት ፋይል ቁጥር፣ ከሌሎች ተባባሪ ቡድኖች ጋር አንድ ዓይነት በሚሆንበት ጊዜ ከፍተኛ እንቅፋት ይፈጥር ነበር። በአሁኑ ጊዜ ያለው አሰራር ግን፣ በአንድ ዓይነት ሰከንድ ውስጥ ብዙ ፍልሰቶች መፍጠሩ ፍጹም ሊሆን እንደማይችል ግምት ውስጥ በማስገባት፣ ማህተመጊዜያቸውን በመጠቀም እነዚህን እንቅፋቶች ለማስወገድ በቅቷል።
ፍልሰቱ ራሱ ለውጡ ወደ ውሂበጎታው እንዲደረግ የሚወስነውን አንድ የ‘ለውጥ (change
) ዘዴን ያካትታል፡፡ በዝርዝር 6.2 ላይ የ‘ለውጥ (change
) ዘዴው በውሂበጎታው ውስጥ ተጠቃሚዎችን ለመያዝ የሚያገለግል አንድ ሰንጠረዥን ለ‘መፍጠር ሰንጠረዥ_ፍጠር (create_table
) የተባለ የሬይልስ ዘዴን ይጠቀማል፡፡ የ‘ሰንጠረዥ_ፍጠር (create_table
) ዘዴው አንድ የጥምር ተለዋዋጪ4 ጋር አንድ ጥምርን ይቀበላል (ክፍል 4.3.2)፣ በዚህ ጉዳይ ላይ ተለዋዋጩ ሰ (t
) (ለ “ሰንጠረዥ (table)”) ይባላል፡፡ በጥምሩ ውስጥ የ‘ሰንጠረዥ_ፍጠር (create_table
) ዘዴው ሁለቱንም የ‘ሃረግ (string
) አይነቶች ማለት የ‘ስም (sim
) እና የ‘ኤመልእክት (emelekt
) አምዶችን በውሂበጎታው ውስጥ ለመፍጠር የ t
ቁስን ይጠቀማል። በዚህ ጊዜ የሰንጠረዡ ስም የብዙ መጠሪያ ስም ማለት:- (ተጠቃሚዎች (teteqamis
)) ሲሆን፤ የቅርጸት ስሙ ግን ነጠላ ማለት:- (ተጠቃሚ (Teteqami)) ነው፡፡ ይህም ቅርጸት አንድ ነጠላ ተጠቃሚን ይወክላል፣ አንድ የውሂበጎታ ሰንጠረዥ ደግሞ ብዙ ተጠቃሚዎችን ይወክላል፣ የሚለውን የሬይል ባህላዊ አባባልን ያመለክታል፡፡ በጥምሩ ውስጥ ያለው፣ የመጨረሻው የ‘ሰ.ማህተመጊዜ (t.timestamps
) መስመር፣ ተፈጠረ_በ (created_at
) እና ተዘመነ_በ (updated_at
) የሚባሉ ሁለት አስማታዊ አምዶችን የሚፈጥር ልዩ ትእዛዝ ነው፣ እነሱም አንድ ተጠቃሚ ልክ ሲፈጠር እና ሲዘምን በራስሰር የሚመዘግቡ ማህተመጊዜወች ናቸው፡፡ (ከክፍል 6.1.3 ጀምሮ ስለ እነዚህ አስማታዊ አምዶች ተጨባጪ የሆኑ ምሳሌዎችን እንመለከታለን፡፡) በዝርዝር 6.2 በፍልሰቱ የቀረበው ሙሉው የውሂብ ቅርጸት በምስል 6.4 ውስጥ ይታያል፡፡ (በምስል 6.3 ላይ በቀረበው ንድፍ ላይ የለሉት አስማታዊ አምዶች እዚህ ላይ እንደቀረቡ ልብ በሉ፡፡)
“ወደ ላይ ማፍለስ (Migrating Up)” በመባል የሚታወቅውን የ‘ውጎ:አፍልስ (db:migrate
) ትእዛዝን እንደሚከተለው አድርገን በመጠቀም ፍልሰቱን ማስኬድ እንችላለን:-
$ rails db:migrate
(በክፍል 2.2 ይህንን ትእዛዝ በአንድ ተመሳሳይ ሁኔታ ላይ እንደተጠቀምንበት ታስታውሱ ይሆናል፡፡) ለመጀመሪያ ጊዜ የ‘ውጎ፡አፍልስ (db:migrate
) ትእዛዙ ሲሄድ፣ አንድ ውጎ/ብልጸጋ.ቀመቋ3 (db/development.sqlite3
) የተባለ ፋይልን ይፈጥራል፤ ይህም አንድ የ‘ቀ.መ.ቋ (SQLite)5 ውሂበጎታ ነው፡፡ የ‘ውጎ/ብልጸጋ.ቀመቋ3 (db/development.sqlite3
) ፋይልን የቀ.መ.ቋ የውሂብጎታ አሳሽን (DB Browser for SQLite) በመጠቀም የውሂበጎታውን መዋቅር ማየት እንችላለን፡፡ (የደመና ቅ.ማ.አን አየተጠቀማችሁ ከሆነ፣ በምስል 6.5 ውስጥ እንደሚታየው፣ በመጀመርያ የውሂበጎታ ፋይሉን በሰፈር ዲስካችሁ ላይ መጫን ይኖርባችኋል)፡፡ በምስል 6.6 ውስጥ የሚታየውን ውጤት ከምስል 6.4 ጋር ስታነጻጽሩ በምስል 6.6 ላይ መታወቂያ (id
) የተባለ ፍልሰትን የማያካትት አንድ አምድ አይታችሁ ሊሆን ይችላል፡፡ በክፍል 2.2 ውስጥ ባጪሩ እንደተገለጸው፣ ይህ አምድ በራስሰር የተፈጠረ ነው፤ እናም ሬይልስም እያንዳንዱን ረድፍ በተናጠል ለመለየት ይጠቀምበታል፡፡
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
db/
) ማውጫ ውስጥ የሚገኘውን እና መርሃግብር.አርቢ (schema.rb
) ተብሎ የሚጠራውን ፋይል ይጠቀማል (ስለሆነም የፋይል ስሙ መርሃግብር (Schema) ተብሎ ይጠራል)፡፡ የናንተን የ‘ውጎ/መርሃግብር.አርቢ (db/schema.rb
) ፋይል ይዞታ ከዝርዝር 6.2 ፍልሰት ኮድ ይዞታ ጋር አነጻጽሩ፡፡
db:rollback
) የተባለውን አንድ ነጠላ ትእዛዝ በመጠቀም ፍልሰቶቹን “ወደ ታች ማፍለስ (Migrate Down)” እና መቀልበስ እንችላለን ማለት ነው:-
$ rails db:rollback
db/schema.rb
) ፋይልን በመመርመር አረጋግጡ፡፡ (ፍልሰቶችን ለመቀልበስ የሚያገለግል ሌላ ጠቃሚ ዘዴ ለማግኘት ሳጥን 3.1 ን ተመልከቱ።) ይህ ትእዛዝ የተጠቃሚዎች ሰንጠረዥን ከውሂበጎታው ላይ ለማስወገድ የ‘ሰንጠረዥ_ጣል (drop_table
) ትእዛዝን በውስጡ ይፈጽማል። ይህ የሚሰራበት ምክንያት የ‘ለውጥ (change
) ዘዴው፣ የ‘ሰንጠረዥ_ጣል (drop_table
) ዘዴ የ‘ሰንጠረዥ_ፍጠር (create_table
) ዘዴ ተገላቢጦሹ መሆኑን ስለሚያውቅ፣ መልሶ መቀልበሱን በቀላሉ መገመት ስለሚችል ነው። የማይቀለበስ ፍልሰትን በተመለከተ፣ ለምሳሌ አንድ የውሂብጎታ አምድን ለማስወገድ፣ ከነጠላው የ‘ለውጥ (change
) ዘዴ ምትክ የተለያዩ የ‘ወደላይ (up
) እና የ‘ወደታች (down
) ዘዴዎችን መበየኑ አስፈላጊ ነው፡፡ ስለ ሬይልስ ፍልሰት ተጨማሪ መረጃ ለማግኘት የሬይልስ መመሪያዎች ላይ ማንበብ ይቻላል።
rails db:migrate
) ትእዛዝን እንደገና በማከናወን ፍልሰቱን እንደገና አስኪዱ። ከዚያ የ‘ውጎ/መርሃግብር.አርቢ (db/schema.rb
) ፋይል ይዞታ ልክ ካሁን በፊት ወደነበረበት ይዞታ መመለሱን አረጋግጡ፡፡
በዝርዝር 6.1 ላይ ያለው የተጠቃሚ ቅርጸት ግኝት እንዴት በዝርዝር 6.2 ላይ ያለውን አንድ የፍልሰት ፋይል እንዳስገኘ አይተናል፣ ይህንን ፍልሰት የማስፈጸም ውጤትንም በምስል 6.6 አይተናል፤ ይህም አንድ ተጠቃሚዎች (teteqamis
) የተባለ ሰንጠረዥ መታወቂያ (id
)፣ ስም (sim
)፣ ኤመልእክት (emelekt
)፣ ተፈጠረ_በ (created_at
) እና ተዘመነ_በ (updated_at
) የተባሉ አምዶችን በመፍጠር ብልጸጋ.ቀመቋ3 (development.sqlite3
) የተባለውን ፋይል እንዳዛመነ አይተናል፡፡ ዝርዝር 6.1 ራሱ ቅርጸቱንም ፈጥሯል፡፡ የዚህ ክፍል ቀሪ ጊዜ፣ እሱን ለመረዳት የተመደበ ይሆናል፡፡
በ‘አፕ/ቅርጸቶች/ (app/models/
) ማውጫ ውስጥ ባለው እና በ‘ተጠቃሚዎች.አርቢ (teteqami.rb
) ፋይል ውስጥ በሚኖረው ማለት የተጠቃሚ ቅርጸት ኮድን በመመልከት እንጀምራለን። ይህም በሌላ አማርኛ፣ በጣም የተጠቀጠቀ ኮድ ነው (ዝርዝር 6.3)።
app/models/teteqami.rb
class Teteqami < ApplicationRecord
end
ክፍል 4.4.2 ላይ ይህ አገባብ class Teteqami < ApplicationRecord
ማለት የ‘ተጠቃሚ (Teteqami
) ክፍል ከ‘አፕልኬሽንመዝገብ (ApplicationRecord
) ክፍል ይወርሳል ማለት ነው ብለን እንደተማርን አስታውሱ፤ ይህ ደግሞ ከ‘አፕልኬሽንመዝገብ::መሰረት (ActiveRecord::Base
) ክፍልም ይወርሳል (ምስል 2.20)፤ በዚህ ምክንያትም የተጠቃሚ ቅርጸቱ የ‘አፕልኬሽንመዝገብ::መሰረት (ActiveRecord::Base
) ተግባራት ሁሉ በራስሰር ይኖረዋል ማለት ነው፡፡ ይህ በንዲህ እንዳለ፣ አፕልኬሽንመዝገብ::መሰረት (ActiveRecord::Base
) የያዘውን ካላወቅን በስተቀር እንዴት እንደሚወራረስ ማወቁ ብቻ የትም አያደርሰንም፤ ስለሆነም አንዳንድ ተጨባጪ በሆኑ ምሳሌዎች እንጀምራለን፡፡
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
Teteqami.new
) የ‘ተጠቃሚ (Teteqami
) ክፍል እንደሆነ እና ከ‘አፕልኬሽንመዝገብ (ApplicationRecord
) እንደሚወርስ አረጋግጡ፡፡
ApplicationRecord
) ከ‘አፕልኬሽንመዝገብ::መሰረት (ActiveRecord::Base
) እንደሚወርስ አረጋግጡ፡፡
በምዕራፍ 4 ላይ እንደተጠቀምንበት ሁሉ፣ አሁንም የውሂብ ቅርጸቶችን ለመመርመር የምንጠቀምበት መሳርያ የሬይልስ ሰሌዳን ይሆናል፡፡ በውሂበጎታችን ላይ ምንም ዓይነት ለውጥ ማድረግ ስለማንፈልግ በአንድ የአሸዋሳጥን (Sandbox) ውስጥ እንጀምራለን:-
$ rails console --sandbox
Loading development environment in sandbox
Any modifications you make will be rolled back on exit
>>
“እናንተ የምታደርጓቸው ማናቸውም ማሻሻያዎች በሙሉ፣ እናንተ በምትወጡበት ጊዜ ወደ ነበሩበት ይመለሳሉ” በሚለው ጠቃሚ መልእክት እንደተመለከተው፣ በአንድ የአሸዋሳጥን ውስጥ ስለጀመርን በዚህ የሰሌዳ ክፍለ ጊዜ ውስጥ የምናደርጋቸውን ማናቸውም የውሂበጎታ ለውጦች ልክ ሰሌዳውን ዘግተን ስንወጣ ሰሌዳው “ቀድሞ ወደ ነበሩበት (roll back)” ሁኔታቸው ይመልሳቸዋል (ማለት ይቀለብሳቸዋል)፡፡
በክፍል 4.4.5 ውስጥ በሰሌዳ ክፍለ ጊዜ፣ በ‘አዲስ.ተጠቃሚ (Teteqami.new
) አንድ አዲስ የተጠቃሚ ቁስን ፈጥረን ነበር፤ ይህን አዲስ ተጠቃሚ በሰሌዳው ውስጥ ልንደርስ የቻልነው በዝርዝር 4.17 ውስጥ የፈጠርነውን የ‘ አብነታዊ_ተጠቃሚ.rb
ፋይልን በሰሌዳው ውስጥ እንዲገኝ የሚያደርገውን የ‘ጠይቅ (require
) ዘዴን በመጠቀም ብቻ ነበረ፡፡ ቅርጸቶችን የሬይልስ ሰሌዳ ውስጥ ለመጠቀም ግን ሁኔታው ለየት ያለ ነው፣ በክፍል 4.4.4 ላይ እንደምታስታውሱት፣ የሬይልስ ሰሌዳ በራስሰር የሬይልስ አካባቢን ይጪናል፤ ይህ ቅርጸቶችንም ያካትታል ማለት ነው። ይህ ማለት ደግሞ ያለምንም ተጨማሪ ስራ አንድ አዲስ የተጠቃሚ ቁስን መስራት እንችላለን ማለት ነው:-
>> Teteqami.new
=> #<Teteqami id: nil, sim: nil, emelekt: nil, created_at: nil, updated_at: nil>
እዚህ ላይ የአንድ የተጠቃሚ ቁስ ነባሪ የሰሌዳ አቀራረብን እናያለን።
ያለምንም ነጋሪአሴት አዲስ.ተጠቃሚ (Teteqami.new
) ብለን ስንጠራ፣ አዲስ.ተጠቃሚ (Teteqami.new
) አንድ ሁሉም ባሕሪወቹ የ‘ምንም (nil
) ዋጋ ያለው ቁስን ይመልሳል። ክፍል 4.4.5 ውስጥ፣ የአብነታዊ ተጠቃሚ ክፍል የቁሱ ባሕሪወችን እንዲያዘጋጅ አንድ የተርታ ማስጀመርያን (Initialization Hash) እንዲወስድ ነድፈን ነበረ፡፡ ለዛ ንድፍ ምርጫ ያነሳሳን የ‘ንቅ መዝገብ ንድፍ ነበር፣ እሱም ቁሶችን በተመሳሳይ መንገድ እንዲጀመሩ ያስችላቸዋል:-
>> ተጠቃሚ = Teteqami.new(sim: "Michael Hartl", emelekt: "michael@misalei.com")
=> #<Teteqami id: nil, sim: "Michael Hartl", emelekt: "michael@misalei.com",
created_at: nil, updated_at: nil>
እዚህ ጋር የስም እና የኤመልእክት ባሕሪወቹ እንደተጠበቀው እንደተዘጋጁ እናያለን።
የማረጋገጫ (Validity) ጽንሰ ሃሳብ የ‘ንቅ መዝገብ ቅርጸት ቁሶችን ለመረዳት አስፈላጊ የሆነ ነገር ነው፡፡ በክፍል 6.2 ውስጥ ይህንን ርዕሰ ጉዳይ በጥልቅ እንመለከተዋለን፤ ላሁኑ ግን ይህ የማስጀመሪያ የ‘ (ተጠቃሚ
) ቁስ ብቁ መሆኑን ማረጋገጡ ጥሩ ነው፤ ይህንንም የ‘ብቁነውን? (valid?
) የቡልየን ዘዴን በቁሱ ላይ በመጥራት ማረጋገጥ እንችላለን:-
>> ተጠቃሚ.valid?
true
አዲስ.ተጠቃሚ (Teteqami.new
) በቀላሉ አንድ አዲስ የተጠቃሚ ቁስን በማህደረ-ትውስታ (Memory) ላይ ሲፈጥር፣ የ‘ተጠቃሚ.ብቁነውን? (ተጠቃሚ.valid?
) ዘዴው ያረገው ነገር ቢኖር ደግሞ ቁሱ ብቁ መሆኑን ማረጋገጥ ብቻ ነበር፤ ስለዚህ እስካሁን ድረስ ውሂበጎታውን አልነካነውም ማለት ነው። የተጠቃሚ ቁሱን ውሂበጎታው ላይ ለማስቀመጥ፣ በ‘ተጠቃሚ (teteqami
) ተለዋዋጩ ላይ የ‘አስቀምጥ (save
) ዘዴን መጥራት ይኖርብናል:-
>> ተጠቃሚ.save
(0.1ms) SAVEPOINT active_record_1
SQL (0.8ms) INSERT INTO "teteqamis" ("sim", "emelekt", "created_at",
"updated_at") VALUES (?, ?, ?, ?) [["sim", "Michael Hartl"],
["emelekt", "michael@misalei.com"], ["created_at", "2019-08-22 01:51:03.453035"],
["updated_at", "2019-08-22 01:51:03.453035"]]
(0.1ms) RELEASE SAVEPOINT active_record_1
=> true
የ‘አስቀምጥ (save
) ዘዴው ነገሩ ከተሳካ እውነት‘ን (true
) ሲመልስ አለበለዚያ ግን ሃሰት‘ን (false
) ይመልሳል፡፡ (በአሁኑ ጊዜ፣ ሁሉን ነገር ውሂበጎታው ላይ የማስፈሩ ጉዳይ ስኬታማ መሆን አለበት፤ ምክንያቱም እስካሁን ድረስ ምንም ዓይነት ማስረገጫ ስለሌለ ነው፣ አንዳንዶቹ ያለብቃት ከማረጋገጫው ሲወድቁ በክፍል 6.2 ላይ እናያለን፡፡) ለማጣቀሻ ያህል የሬይልስ ሰሌዳ እንዲሁ ከ‘ተጠቃሚ.አስቀምጥ (ተጠቃሚ.save
) ዘዴ ጋር የሚዛመደውን የተ.መ.ቋ ትእዛዝን ያሳያል (ማለትም INSERT INTO "teteqamis"
…)፡፡ በዚህ መጽሐፍ6 ውስጥ ጥሬ ተ.መ.ቋ በጪራሽ አያስፈልገንም፣ እኔም ከአሁን ወዲያ ስለ ተ.መ.ቋ ትእዛዞች መናገሩን ከወዲሁ አቆማለሁ፣ ነገር ግን ከ‘ንቅ መዝገብ ትእዛዞች ጋር የሚዛመደውን ተ.መ.ቋ በማንበብ ብዙ መማር እንደምትችሉ ላስገነዝባችሁ እወዳለሁ።
አዲሱ የተጠቃሚ ቁስ ለ‘መታወቂያ (id
) እና ለአስማታውያኖቹ አምዶች ማለት ለ‘ተፈጠረ_በ (created_at
) እና ለ‘ተዘመነ_በ (updated_at
) ባሕሪወች የነበሩት ዋጋወች ምንም (nil
) እንደነበሩ አስተውላችሁ ይሆናል። እስኪ የኛ የ‘አስቀምጥ (save
) ዘዴ የሆነ ነገርን ለውጦ ከሆነ እንመልከት:-
>> ተጠቃሚ
=> #<User id: 1, name: "Michael Hartl", email: "michael@example.com",
created_at: "2019-08-22 01:51:03", updated_at: "2019-08-22 01:51:03">
መታወቂያ‘ው (id
) አንድ የ 1
ዋጋ ሲመደብለት፣ ለአስማተኞቹ አምዶች ደግሞ የወቅቱ ቀን እና ጊዜ7 እንደተመደበላቸው እናያለን፡፡ በአሁኑ ጊዜ፣ የተፈጠሩበት እና የተዘመኑበት ማህተመጊዜወች ፍጹም አንድ ናቸው፣ ነገር ግን በክፍል 6.1.5 ውስጥ እነዚህ ማህተመጊዜወች የተለያዩ ሲሆኑ እንመለከታለን፡፡
በክፍል 4.4.5 ውስጥ የተጠቃሚ ክፍል ላይ እንደተጠቀምነው ሁሉ፣ የተጠቃሚ ቅርጸት ቅርፀቶችም የነጥብ ስርዓተ-ምልክትን በመጠቀም ባሕሪያቸው እንዲደረስ ይፈቅዳሉ:-
>> ተጠቃሚ.sim
=> "Michael Hartl"
>> ተጠቃሚ.emelekt
=> "michael@misalei.com"
>> ተጠቃሚ.updated_at
=> Fri, 06 Nov 2020 03:03:14 UTC +00:00
በምዕራፍ 7 ላይ እንደምናየው፣ ከዚህ በላይ እንዳየነው አንድ ቅርጸትን በሁለት ሂደት ውስጥ ማለት መጀመሪያ መስራት እና ከዚያ ማስቀመጡ ብዙውን ጊዜ ምቹ የሆነ የአሰራር ስልት ነው፣ ነገር ግን ንቅ መዝገብ እንዲሁም በ‘ተጠቃሚ.ፍጠር (Teteqami.create
) እነዚህን ሁለት ሂደቶች ወደ አንድ ሂደት እንድታጣምሯቸው ያደርጋችኋል:-
>> Teteqami.create(sim: "አብርሃም ቹቹ", emelekt: "abrham@chuchu.org")
#<Teteqami id: 2, sim: "አብርሃም ቹቹ", emelekt: "abrham@chuchu.org", created_at:
"2020-11-06 17:25:49", updated_at: "2020-11-06 17:25:49">
>> ሶል = Teteqami.create(sim: "ሶል", emelekt: "sole@gere.com")
#<Teteqami id: 3, sim: "ሶል", emelekt: "sole@gere.com", created_at: "2020-11-06
17:28:50", updated_at: "2020-11-06 17:28:50">
የ‘ተጠቃሚ.ፍጠር (Teteqami.create
) ዘዴው እውነት (true
) ወይም ሃሰትን (false
) ከመመለስ ይልቅ ራሱን የተጠቃሚ ቁሱን ይመልሳል፣ ይህንንም ከአንድ ምርጫዊ ተለዋዋጪ ጋር ልንበይነው እንደምንችል ልታስተውሉ ይገባል፡፡ (ይህ ማለትም ልክ ከላይ ሁለተኛው ትእዛዝ ላይ እንዳለው ሶል
እንደተባለው ተለዋዋጪ ማለት ነው)።
የ‘ፍጠር (create
) ተቃራኒ አጥፋ (destroy
) ነው:-
>> ሶል.destroy
(0.1ms) SAVEPOINT active_record_1
SQL (0.2ms) DELETE FROM "teteqamis" WHERE "teteqamis"."id" = ? [["id", 3]]
(0.1ms) RELEASE SAVEPOINT active_record_1
=> #<Teteqami id: 3, sim: "ሶል", emelekt: "sole@gere.com", created_at:
"2020-11-06 17:28:50", updated_at: "2020-11-06 17:28:50">
ልክ እንደ ፍጠር (create
) የ‘አጥፋ (destroy
) ዘዴም ለተጠየቀው መጠይቅ ቁሱን በመመለስ ድርጊቱን ይፈጽማል፣ እኔ በበኩሌ የ‘አጥፋ (destroy
) ምላሽን የተጠቀምኩበትን ጊዜ በፍጹም አላስታውሰውም። ከዚያ በባሰ መልኩ ደግሞ ይሄው የጠፋው ቁስ እስከ አሁን ድረስ በማህደረ-ትውስታው ውስጥ ይገኛል:-
>> ሶል
=> #<Teteqami id: 3, sim: "ሶል", emelekt: "sole@gere.com", created_at:
"2020-11-06 17:28:50", updated_at: "2020-11-06 17:28:50">
ስለዚህ አንድ ቁስን በትክክል እንዳጠፋን እንዴት እናውቃለን? የተቀመጡ እና ያልጠፉ ቁሶችን እንዴት ከውሂበጎታው ውስጥ ፈልገን ማግኘት እንችላለን? ለእነዚህ መጠይቆች መልስ ለመስጠት ንቅ መዝገብን እንዴት መጠቀም እንደምንችል መማር ይጠበቅብናል፡፡
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
ተጠቃሚ.sim
) እና ተጠቃሚ.ኤመልእክት (ተጠቃሚ.emelekt
) የ‘ሃረግ (String
) ክፍል መሆናቸውን አረጋግጡ፡፡
created_at
) እና የ‘ተዘመነ_በ (updated_at
) ባሕሪወች የማን ክፍል አባላቶች ናቸው?
ንቅ መዝገብ ቁሶችን ለመፈለግ በርካታ አማራጮችን ያቀርባል፡፡ ሶል
የተባለው ሶስተኛው ተጠቃሚ ከውሂበጎታው ማጥፋቱን ለማረጋገጥ እና ባለፈው ጊዜ መጀመሪያ ላይ የፈጠርነውን ተጠቃሚ ለማግኘት እንችል ዘንድ ጥቂቶቹን የ‘ንቅ መዝገብ ዘዴወች እንጠቀምባቸዋለን፡፡ በሚኖረው ተጠቃሚ እንጀምራለን:-
>> Teteqami.find(1)
=> #<Teteqami id: 1, sim: "Michael Hartl", emelekt: "michael@misalei.com",
created_at: "2020-11-06 03:03:14", updated_at: "2020-11-06 03:03:14">
እዚህ ላይ የተጠቃሚውን መታወቂያ ወደ ተጠቃሚ.ፈልግ (Teteqami.find
) አሳለፍን፤ እናም ንቅ መዝገብ ተጠቃሚውን ከዚያ መታወቂያ ጋር ይመልሳል።
እስኪ በ‘መታወቂያ (id
) ቁጥር 3
የሚታወቀው ተጠቃሚ እስከ አሁን ድረስ በውሂበጎታው ውስጥ መኖሩን እንይ:-
>> Teteqami.find(3)
ActiveRecord::RecordNotFound (Couldn't find Teteqami with 'id'=3)
ሶስተኛውን ተጠቃሚ በክፍል 6.1.3 ላይ ስላጠፋነው ንቅ መዝገብ በውሂበጎታው ውስጥ ሊያገኘው አልቻለም፡፡ እንዳውም የ‘ፈልግ (find
) ዘዴ በምትኩ አንድ ልዩነትን (Exception) ያስነሳል፣ ይህ ማለትም በአንድ ፕሮግራም አፈጻጸም ሂደት ውስጥ በፕሮግራሙ ላይ ለየት ያለ ሁኔታ እንዳለ የሚያመላክትበት አንዱ መንገድ ሲሆን፣ በዚህ ሁኔታ ላይ፣ በ‘ንቅ መዝገብ ውስጥ የአንድ መታወቂያ አለመኖርን ነው፤ በዚህ ምክንያትም ፈልግ‘ን (find
) አንድ የ‘ንቅመዝገብ::መዝገብአልተገኘም (ActiveRecord::RecordNotFound
) ልዩነትን8 እንዲያስነሳ አብቅቶታል፡፡
ከአጠቃላዩ የ‘ፈልግ (find
) ዘዴ በተጨማሪ፣ ንቅ መዝገብም ተጠቃሚዎችን በተወሰኑ ባሕሪወች እንድንፈልግም ያደርገናል፡-
>> Teteqami.find_by(emelekt: "michael@misalei.com")
=> #<Teteqami id: 1, sim: "Michael Hartl", emelekt: "michael@misalei.com",
created_at: "2019-08-22 01:51:03", updated_at: "2019-08-22 01:51:03">
የኤመልእክት አድራሻዎችን ልክ እንደ የተጠቃሚስሞች (Usernames) አድርገን ስለምንጠቀምባቸው፣ የዚህ ዓይነት የ‘ፈልግ (find
) ዘዴ ጠቃሚ የሚሆነው ተጠቃሚዎችን እንዴት አድርገን ወደ ጣቢያችን እንደምናስገባ ስንማር ነው (ምዕራፍ 7)፡፡ በርከት ያለ ቁጥር ያላቸው ተጠቃሚዎች በውሂበጎታ ውስጥ ካሉ የ‘ፈልግ_በ (find_by
) ዘዴ ውጤታማ አይሆንም የሚል ስጋት ካደረባችሁ፣ እናንተ ከጨዋታው ቀድማችሁ ሂዳችኋል ማለት ነው፤ በክፍል 6.2.5 ውስጥ፣ ይህንን ጉዳይ እና የሱን መፍትሄ በውሂበጎታ መረጃ-ጠቋሚዎች በኩል እንዴት እንደምናገኝ እንሸፍናለን።
በአጠቃላይ ተጠቃሚዎችን ለመፈለግ የሚያስችሉ አንድ ሁለት የተለያዩ መንገዶችን በመመልከት እንጨርሳለን፡፡ በመጀመሪያ ስንጀምርም አንደኛ (first
) የሚባል ዘዴም አለ:-
>> Teteqami.first
=> #<Teteqami id: 1, sim: "Michael Hartl", emelekt: "michael@misalei.com",
created_at: "2019-08-22 01:51:03", updated_at: "2019-08-22 01:51:03">
አንደኛ (first
) በተፈጥሮው ከውሂበጎታው ውስጥ የመጀመሪያውን ተጠቃሚ ይመልሳል። ሁሉም (all
) የሚባል ዘዴም አለ:-
>> Teteqami.all
=> #<ActiveRecord::Relation [#<Teteqami id: 1, sim: "Michael Hartl", emelekt:
"michael@misalei.com", created_at: "2020-11-06 03:03:14", updated_at:
"2020-11-06 03:03:14">, #<Teteqami id: 2, sim: "አብርሃም ቹቹ", emelekt:
"abrham@chuchu.org", created_at: "2020-11-06 17:25:49", updated_at:
"2020-11-06 17:25:49">]>
ከሰሌዳው ውጽአት ላይ ማየት እንደምትችሉት፣ ሁሉም.ተጠቃሚ (Teteqami.all
) በውሂበጎታው ውስጥ ያሉትን ሁሉንም ተጠቃሚዎች ልክ እንደ አንድ የ‘ንቅመዝገብ::ዝምድና (ActiveRecord::Relation
) ክፍል ቁስ አድርጎ ይመልሳል፣ ይህ የተመለሰው ቁስም አንድ ድርድር ነው (ክፍል 4.3.1)፡፡
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
sim
) ፈልጉ። በ‘ስም_ፈልግ‘ም (find_by_sim
) እንደሚሰራ አረጋግጡ፡፡ (ብዙውን ጊዜ ፈልግ_በ‘ን (find_by
) ቆየት ብለው በተሰሩ የሬይልስ አፕልኬሽኖች ላይ ልታዩት ትችላላችሁ።)
Teteqami.all
) ልክ እንደ አንድ ድርድር ሁኖ ይሰራል፣ ይሁን እንጅ በእውነቱ የ‘ተጠቃሚ::ንቅመዝገብ_ዝምድና (Teteqami::ActiveRecord_Relation
) ክፍል መሆኑን አረጋግጡ፡፡
Teteqami.all
) ላይ የ‘እርዝመት (length
) ዘዴን በማሳለፍ፣ የሁሉንም ተጠቃሚ እርዝመትን መፈለግ እንደምትችሉ አረጋግጡ (ክፍል 4.2.2)፡፡ ሩቢ ቁሶችን የማንቀሳቀስ ችሎታው በቁሶቹ መደበኛ የክፍል ዓይነት ላይ የተመሰረተ ሳይሆን፣ በቁሶቹ ድርጊት ላይ የተመሰረተ ስለሆነ፣ ይህ አሰራር በሩቢ ውስጥ “የዳክየ አሰራር (Duck Typing)” ተብሎ ይጠራል። “ዳክዬ ከመሰለ እና እንደ ዳክዬ “ኩኩ...” ካለ ዳክዬ መሆን አለበት” በተባለው አባባል ላይ የተመሰረተ የአሰራር ሂደት ነው፡፡
አንዴ ቁሶችን ከፈጠርን በኋላ፣ ብዙውን ጊዜ ልናዘምናቸው እንፈልጋለን። ይህንን ለማድረግም ሁለት መሰረታዊ መንገዶች አሉ፡፡ በመጀመሪያ በክፍል 4.4.5 ላይ እንዳደረግነው፣ ባሕሪወቹን በተናጥል መመደብ እንችላለን:-
>> ተጠቃሚ # የተጠቃሚውን ባሕሪዎች ለማስታወስ ብቻ
=> #<Teteqami id: 1, sim: "Michael Hartl", emelekt: "michael@misalei.com",
created_at: "2019-08-22 01:51:03", updated_at: "2019-08-22 01:51:03">
>> ተጠቃሚ.emelekt = "mhartl@misalei.net"
=> "mhartl@misalei.net"
>> ተጠቃሚ.save
=> true
ያደረግናቸውን ለውጦቹ በውሂበጎታው ላይ ለማስፈር የመጨረሻው ሂደት አስፈላጊ መሆኑን ልብ በሉ፡፡ በውሂበጎታው መረጃ ላይ በመመርኮዝ ቁሱን እንደገና የሚጪነውን ዳግምጫን‘ን (reload
) በመጠቀም፣ የተደረገው ለውጥ ውሂበጎታው ላይ ካልተቀመጠ ምን እንደሚከሰት ማየት እንችላለን:-
>> ተጠቃሚ.emelekt
=> "mhartl@misalei.net"
>> ተጠቃሚ.emelekt = "sole@gere.com"
=> "sole@gere.com"
>> ተጠቃሚ.reload.emelekt
=> "mhartl@misalei.net"
አሁን ተጠቃሚ.አስቀምጥ‘ን (ተጠቃሚ.save
) በማስኬድ ተጠቃሚውን አዘምነናል፣ በክፍል 6.1.3 ውስጥ ቃል በተገባው መሰረትም አሁን የነዚህ አስማተኛ አምዶች ማህተመጊዜም የተለያየ ሁኗል:-
>> ተጠቃሚ.created_at
=> Thu, 22 Aug 2019 01:51:03 UTC +00:00
>> ተጠቃሚ.updated_at
=> Thu, 22 Aug 2019 01:58:08 UTC +00:00
በርካታ ባሕሪወችን ባአንዴ ለማዘመን ከተፈለገ ደግሞ፣ ሁለተኛውን ማለት አዘምን‘ን (update
)9 መጠቀም ይሆናል:-
>> ተጠቃሚ.update(sim: "ሰለሞን አንበሴ", emelekt: "selemon@anbesie.org")
=> true
>> ተጠቃሚ.sim
=> "ሰለሞን አንበሴ"
>> ተጠቃሚ.emelekt
=> "selemon@anbesie.org"
የ‘አዘምን (update
) ዘዴ አንድ የተርታ ባሕሪወችን ይቀበላል፣ ሁሉም ነገር ያለምንም ችግር ከተሳካ፣ ሁለቱንም ማለት ማዘመኑን እና ማስቀመጡን በአንድ ጊዜ ያከናውናል (መቀመጡ መሳካቱን ለማመልከት እውነት‘ን (true
) ይመልሳል)። እዚህ ላይ ማስታዋል የሚገባን አንድ ነገር ቢኖር፣ (በክፍል 6.3 ላይ ተግባራዊ እንደሆነው) አንድ መረጃን ለማስቀመጥ አንድ መሕለፈቃል ግዴታ በሚያስፈልግበት ወቅት፣ ማናቸውም ማስረገጫዎች ካልተሳኩ አዘምን (update
) ላይ የሚደረገው ጥሪ ውድቅ እንደሚሆን ነው፡፡ አንድ ነጠላ ባሕሪን ብቻ ማዘመን ከፈለግን፣ የነጠላውን ማለት የ‘ባሕሪ_አዘምን (update_attribute
) ዘዴን በመጠቀም የማስረገጫዎቹን የክልከላ አጥር በመዝለል ይህንን እገዳ እንዲህ አድርገን መጣስ እንችላለን:-
>> ተጠቃሚ.update_attribute(:sim, "ነጋ ገብረስላሰ")
=> true
>> ተጠቃሚ.sim
=> "ነጋ ገብረስላሰ"
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
save
) ጥሪን በመጠቀም የተጠቃሚውን ስም አዘምኑ።
update
) ጥሪን በመጠቀም የተጠቃሚውን የኤመልእክት አድራሻ አዘምኑ።
save
) ጥሪን በመጠቀም የ‘ተፈጠረ_በ (created_at
) አምድን በማዘመን አስማታዊ አምዶቹን በቀጥታ መለወጥ እንደምትችሉ አረጋግጡ፡፡ ዋጋውን ከ‘1.ዓመት.በፊት (1.year.ago
) ብላችሁ ተጠቀሙ፣ ይህም በሬይልስ ከአንድ ዓመት በፊት የተፈጸመ አንድ ማህተመጊዜን የመፍጠሪያ አንዱ መንገድ ነው።
በክፍል 6.1 ውስጥ የፈጠርነው የተጠቃሚ ቅርጸት አሁን የሚሰራ የ‘ስም (sim
) እና የ‘ኤመልእክት (emelekt
) ባሕሪወች አሉት፤ ይሁን እንጅ ሁለቱም ባሕሪወች ባዶ ሃረግንም ሳይቀር ያገኙትን ሃረግ ልክ እንደ ብቁ አድርገው ያግበሰብሳሉ፤ በነሱ ቤት እነዚህ ሁኔታዎች ተቀባይነት አላቸው፡፡ ይሁን እንጂ አሁንም ቢሆን ስሞች እና የኤመልእክት አድራሻዎች ከዚህ በበለጠ የተወሰኑ መሆን አላባቸው፡፡ ለምሳሌ ስም (sim
) ባዶ መሆን የለበትም፤ የ‘ኤመልእክት (emelekt
) ደግሞ ከተለየ የኤመልእክት አድራሻ የቅርጸት ባህሪ ጋር መዛመድ አለበት፡፡ በተጨማሪም ተጠቃሚዎች በሚገቡበት ጊዜ የኤመልእክት አድራሻዎችን እንደ ልዩ የተጠቃሚስም ስለምንጠቀምበት፣ በውሂበጎታው ውስጥ አንድ ዓይነት የሆነ የኤመልእክት አድራሻ እንዲደጋገም መፍቀድ የለብንም፡፡
ባጪሩ ስም (sim
) እና ኤመልእክት (emelekt
) ልክ እንደ ማንኛውም ተራ ሃረግ እንዲሆኑ መፍቀድ የለብንም፤ በዋጋቸው ላይ የተወሰኑ ገደቦችን ማስቀመጥ ይኖርብናል። ንቅ መዝገብ ማስረገጫዎችን በመጠቀም እንደዚህ ያሉ ገደቦችን እንድናደርግ ይፈቅድልናል (ከዚህ በፊት በክፍል 2.3.2 ላይ ባጪሩ ታይቷል)። በዚህ ክፍል ውስጥ፣ ብዙውን ጊዜ ለተለመዱ ምክንያቶች ማስረገጫነት የሚያገለግሉ ዘዴወችን እንመላከታለን። ከእነዚህም መካከል መኖርን (presence)፣ እርዝመትን (length)፣ ቅርጸትን (format) እና ልዩነትን (uniqueness) የሚያረጋግጡ ዘዴወች ይገኙባቸዋል። በክፍል 6.3.2 መጨረሻ ላይ አንድ የተለመደ ማለት ማስረገጫ (Confirmation) የተባለ የማጽናት ማስረገጫን እንጨምር እና፣ ተጠቃሚዎች ደንቦቹን የሚጥሱ ርክቦችን ሲያቀርቡ፣ ማስረገጫዎቹ እንዴት አድርገው የሚመቹ የስህተት መልእክቶችን እንደሚሰጡን በክፍል 7.3 ላይ እናያለን፡፡
በሳጥን 3.3 ላይ እንደተጠቀሰው፣ ፈተና-መሬ ብልጸጋ ሁልጊዜ ለሁሉ ስራ ትክክለኛ መሳሪያ አይሆንም፤ ነገር ግን የቅርጸት ማረገጫዎች በትክክል የፈተና-መሬ ብልጸጋ የሚገቧቸው ዓይነት በይነገጽታዎች ናቸው፡፡ አንድ የውድቀት ፈተና ተጽፎ ከዚያም እንዲያልፍ ካልተደረገ በስተቀር፣ አንድ የተሰጠ ማስረገጫ በትክክል የሚጠበቀውን ስራ እየሰራ መሆኑን እርግጠኛ ለመሆን በጣም ከባድ ነው።
ዘዴያችን በአንድ ብቁ የቅርጸት ቁስ ይጀምራል፤ ከዚያ ከባሕሪወቹ ውስጥ አንዱን ባሕሪ እኛ ብቁ እንዳይሆን በፈለግነው ነገር እናዘጋጅዋለን፣ ከዚያም በትክክል ብቁ አለመሆኑን እንፈትነዋለን፡፡ ልክ እንደ አንድ የደህንነት መረብ ይሆነን ዘንድ፣ የማስጀመሪያ ቅርጸቱ ብቁ መሆኑን ለማረጋገጥ በመጀመሪያ አንድ ፈተና እንጽፋለን። በዚህ መንገድ የማስረገጫ ፈተናወቹ ሳያልፉ ሲቀሩ፣ መውደቃቸው በትክክለኛው ምክንያት እንደሆነ እናውቃለን ማለት ነው (እናም ምክንያቱ የማስጀመሪያ ቁሱ ከድሮው ብቁ ስላልሆነ እንዳልሆነ እናውቃለን ማለት ነው)።
በሚቀጥለው ክፍለ ጊዜ እና በአጠቃላይ ፈ.መ.ብን በምትሰሩበት ጊዜ፣ የጽሑፍ አርታኢውን ለሁለት ቦታ በመክፈል ማለት በግራ በኩል የፈተና ኮዱን፣ በቀኝ በኩል ደግሞ የአፕልኬሽኑን ኮድ አድርጎ መስራቱ በጣም አመች ይሆናል፡፡ የኔ የደመና ቅ.ማ.አ የአወቃቀር ምርጫየ በምስል 6.7 ውስጥ ይታያል፡፡
በዝርዝር 6.1 ውስጥ ያለው ትእዛዝ ተጠቃሚዎችን መፈተን እንድንጀምር አንድ የማስጀመሪያ ፈተናን ቢፈጥርም እንኳን፣ አሁን ባለው ሁኔታ ላይ ግን የፈጠረው ፈተና ጪራሽ ባዶ ነው (ዝርዝር 6.4)፡፡
test/models/teteqami_test.rb
require 'test_helper'
class TeteqamiTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end
አንድ የቁስ ብቃት ፈተናን ለመጻፍ፣ በመጀመሪያ ከእያንዳንዱ ፈተና በፊት በራስሰር የሚሄድ ልዩ የአዘጋጅ (setup
) ዘዴን (በምዕራፍ 3 መልመጃዎች ውስጥ በደንብ ተብራርቷል) በመጠቀም፣ አንድ የማስጀመርያ ብቁ የ‘@ተጠቃሚ (@teteqami
) ቅርጸት ቁስን እንፈጥራለን፣ @ተጠቃሚ (@teteqami
) ቅርፀ ተለዋዋጪ ስለሆነ፣ በሁሉም ፈተናወች ውስጥ በራስሰር ይገኛል፣ እናም የ‘ብቁነውን? (valid?
) ዘዴን በመጠቀም፣ ብቃቱን መፈተን እንችላለን (ክፍል 6.1.3)፡፡ ውጤቱ በዝርዝር 6.5 ውስጥ ይታያል፡፡
test/models/teteqami_test.rb
require 'test_helper'
class TeteqamiTest < ActiveSupport::TestCase
def setup
@teteqami = Teteqami.new(sim: "Abnetawi Teteqami", emelekt: "teteqami@misalei.com")
end
test "ብቁ መሆን አለበት" do
assert @teteqami.valid?
end
end
ዝርዝር 6.5 የ‘አረጋግጥ (assert
) ዘዴን በጥሬው ይጠቀማል፣ በዚህ ሁኔታ ላይ ተጠቃሚ.ብቁነውን? (@teteqami.valid?
) ከተሳካ እውነት‘ን (true
) ካልሆነ ደግሞ ሃሰት‘ን (false
) ይመልሳል።
በአሁኑ ጊዜ የተጠቃሚ ቅርጸታችን ምንም ዓይነት ማስረገጫ ስለለው፣ ይህ የማስጀመሪያ ፈተና ማለፍ አለበት:-
$ rails test:models
እዚህ ላይ የቅርጸት ፈተናወችን ብቻ ለማስኬድ ሬይልስ ቅርጸቶች:ፈትን‘ን (rails test:models
) ተጠቅመናል፣ (ይህንን ክፍል 5.3.4 ላይ ካለው የውህደት ፈተናን ለማስኬድ ከተጠቀምንበት ከ‘ሬይልስ ውህደት:ፈትን (rails test:integration
) ትእዛዝ ጋር አነጻጽሩ)፡፡
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
ምናልባት ካሉት ማስረገጫወች ውስጥ ሁሉ መሰረታዊ የሆነ ማስረገጫ ቢኖር የመኖር (Presence) ማስረገጫ ነው፣ ጥቅሙም አንድ የተሰጠ ባሕሪ መኖሩን ማረጋገጥ ብቻ ነው። ለምሳሌ:- በዚህ ክፍለ ጊዜ፣ የአንድ ተጠቃሚ መረጃ ውሂበጎታው ላይ ከመቀመጡ በፊት ሁለቱም ማለት የስም እና የኤመልእክት መስኮቹ መኖራቸውን እናረጋግጣለን፡፡ በክፍል 7.3.3 ላይ አዲስ ተጠቃሚዎችን ለመፍጠር በመመዝገቢያ ቅጹ ላይ ይህንን መስፈርት እንዴት እንደምናስፋፋ እንመለከታለን፡፡
በዝርዝር 6.5 ውስጥ ያለውን አንድ ፈተና መሰረት በማድረግ፣ አንድ የ‘ስም (sim
) ባሕሪ መኖሩን በመፈተን እንጀምራለን፡፡ በዝርዝር 6.7 ላይ እንደምንመለከተው፣ ማድረግ ያለብን ነገር ቢኖር @ተጠቃሚ (@teteqami
) ተለዋዋጪን ከአንድ ባዶ የ‘ስም (sim
) ባሕሪ ሃረግ ጋር ማዘጋጀት ነው (በዚህ ሁኔታ ላይ፣ አንድ የክፍትቦታወች ሃረግ ይሆናል) ከዚያም (የ‘አለመሆኑን_አረጋግጥ (assert_not
) ዘዴን በመጠቀም) የተገኘው የተጠቃሚ ቁሱ ብቁ እንዳልሆነ እንፈትሻለን፡፡
sim
) ባሕሪ ማረጋገጫ ፈተና። ቀይ test/models/teteqami_test.rb
require 'test_helper'
class TeteqamiTest < ActiveSupport::TestCase
def setup
@teteqami = Teteqami.new(sim: "Abnetawi Teteqami", emelekt: "teteqami@misalei.com")
end
test "ብቁ መሆን አለበት" do
assert @teteqami.valid?
end
test "ስም መኖር አለበት" do
@teteqami.sim = " "
assert_not @teteqami.valid?
end
end
በዚህ ጊዜ የቅርጸት ፈተናው ቀይመሆን አለበት:-
$ rails test:models
ከዚህ በፊት በምዕራፍ 2 መልመጃዎች ላይ ባጪሩ እንዳየነው፣ የስም ባሕሪ መኖሩን የማስረገጫው መንገድ በዝርዝር 6.9 ላይ እንደሚታየው፣ የ‘አስረግጥ (validates
) ዘዴን ከመኖር፡ እውነት (presence: true
) ነጋሪአሴት ጋር መጠቀም ነው፡፡ የባሕሪ መኖር ማስረገጫው ማለት የ‘መኖር፡ እውነት (presence: true
) ነጋሪአሴቱ የሚወስደው አንድ የተርታ አማራጪ ብቻ ነው፤ ተርታወች የመጨረሻ ነጋሪአሴት ሁነው ወደ አንድ ዘዴ በሚያልፉበት ጊዜ፣ በክፍል 4.3.4 ላይ እንደተማርነው የሐረግ ቅንፎቻቸውን መጠቀም እና አለመጠቀም ምርጫዊ እንደሆነ ሳታስታውሱ የምትቀሩም አይመስለኝም። (በክፍል 5.1.1 ላይ እንደተመለከተው፣ በሬይልስ ውስጥ የተርታዎች አማራጮችን መጠቀሙ አንድ ተደጋጋሚ የሆነ ገጽታ ነው።)
sim
) ባሕሪ መኖሩን ማረጋገጥ። አረንጓዴ app/models/teteqami.rb
class Teteqami < ApplicationRecord
validates :sim, presence: true
end
ዝርዝር 6.9 በአስማት የሚሰራ ይመስላል፣ ነገር ግን አስረግጥ (validates
) አንድ ዘዴ ብቻ ነው፡፡ ቅንፎችን በመጠቀም በዝርዝር 6.9 ውስጥ ያለው የ‘አስረግጥ (validates
) ዘዴ ምስረታ ሲጻፍ አንደሚከተለው ነው:-
class Teteqami < ApplicationRecord
validates(:sim, presence: true)
end
በተጠቃሚ ቅርጸታችን10 ላይ አንድ ማስረገጫ በመታከሉ ምክንያት የመጣውን ውጤት ለመመልከት እስኪ ወደ ሰሌዳው ጎራ እንበል:-
$ rails console --sandbox
>> ተጠቃሚ = Teteqami.new(sim: "", emelekt: "michael@misalei.com")
>> ተጠቃሚ.valid?
=> false
እዚህ ላይ አንድ ቁስ ከአንድ ወይም ከዚያ በላይ ማስረጋገጫዎችን ሲወድቅ ሃሰት‘ን (false
) እና ሁሉንም ማስረገጫዎች በሚያልፍበት ጊዜ ደግሞ ለማለፉ እውነትን (true
) የሚሰጠውን የ‘ብቁነውን? (valid?
) ዘዴን በመጠቀም የ‘ተጠቃሚ (teteqami
) ተለዋዋጪን ፈትሸናል። በዚህ ጊዜ ያለን ማስረገጫ አንድ ብቻ ነው፤ ስለሆነም የትኛው እንዳለፈ ያለ ምንም ጥርጥር ማወቅ እንችላለን፣ ነገር ግን ስህተቶች‘ን (errors
) በመጠቀም በውድቀቱ ምክንያት የመነጨውን ቁስ መመርመሩ አሁንም ቢሆን ጠቃሚ ሊሆን ይችላል:-
>> ተጠቃሚ.errors.full_messages
=> ["Sim can't be blank"]
(የስህተት መልእክቱ ሬይልስ የ‘ባዶነውን? (blank?
) ዘዴን በመጠቀም አንድ ባሕሪ መኖሩን እንደሚያረጋግጥ የሚመሰክር አንድ ፍንጪ ነው፣ ይህንን ዘዴም በክፍል 4.4.3 መጨረሻ ላይ አይተነዋል፡፡)
የተጠቃሚው መስፈርት ብቁ ስላልሆነ፣ ተጠቃሚውን በውሂበጎታው ላይ ለማስቀመጥ የሚደረገው ፈተና በራስሰር ውድቅ ይሆናል:-
>> ተጠቃሚ.save
=> false
በዚህ ምክንያትም፣ በዝርዝር 6.7 ውስጥ ያለው ፈተና አሁን አረንጓዴመሆን አለበት፡-
$ rails test:models
የአፕልኬሽኑ ኮድ ፈተናውን ለማለፍ እንዲበቃ፣ (ዝርዝር 6.11) በዝርዝር 6.7 ውስጥ ያለውን ቅድ በመከተል የ‘ኤመልእክት (emelekt
) ባሕሪው መኖሩን ለማረጋገጥ አንድ ፈተና መጻፉ በጣም ቀላል ነው (ዝርዝር 6.12)
emelekt
) ባሕሪ ማረጋገጫ ፈተና። ቀይ test/models/teteqami_test.rb
require 'test_helper'
class TeteqamiTest < ActiveSupport::TestCase
def setup
@teteqami = Teteqami.new(sim: "Abnetawi Teteqami", emelekt: "teteqami@misalei.com")
end
test "ብቁ መሆን አለበት" do
assert @teteqami.valid?
end
test "ስም መኖር አለበት" do
@teteqami.sim = " "
assert_not @teteqami.valid?
end
test "ኤመልእክት መኖር አለበት" do
@teteqami.emelekt = " "
assert_not @teteqami.valid?
end
end
emelekt
) ባሕሪ መኖሩን ማረጋገጥ። አረንጓዴ app/models/teteqami.rb
class Teteqami < ApplicationRecord
validates :sim, presence: true
validates :emelekt, presence: true
end
በዚህ ጊዜ፣ የመኖር ማስረገጫዎች ተጠናቀዋል እና የፈተና ስብስቡ አረንጓዴመሆን አለበት:-
$ rails test
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
ቶማስ
የተባለ ተጠቃሚ ፍጠሩ እና መጀመሪያ ብቁ እንዳልሆነ አረጋግጡ፡፡ የቁሱ ሙሉ የስህተት መልእክቶች ምን ይላል?
ቶማስ.errors.messages
) አንድ የስህተቶች ተርታ መሆኑን አረጋግጡ፡፡ በቶማስ የኤመልእክት አድራሻ ላይ ብቻ የተፈጠረውን ስህተት እንዴት መድረስ ትችላላችሁ?
የተጠቃሚ ቅርጸታችንን ለእያንዳንዱ ተጠቃሚ አንድ ስም እንደሚያስፈልገው ገድበነው ነበር፣ ነገር ግን ከዚያ ገደብ ባሻገር መሄድ አለብን፤ በጣቢያችን ላይ የተጠቃሚው ስም ስለሚታይ፣ የስሙ እርዝመት ላይ የተወሰነ ገደብን ማስቀመጥ ይኖርብናል፡፡ ይህ ሂደት በክፍል 6.2.2 ውስጥ ካደረግነው ሂደት ሁሉ የቀለለ ሂደት ነው፡፡
አንድ ከፍተኛ እርዝመትን ለመምረጥ የሚረዳ ሳይንስ የለም፤ ስለዚህ ያገራችን ደብር ያውቃል ብለን 50
ቁጥርን እንመርጥ እና እሱኑ ልክ እንደ አንድ ከፍተኛ ወሰን አድርገን እንወስደዋለን፣ ይህ ማለት የሚቀርበው ስም ሆሄው 51
እና ከዚያ በላይ ከሆነ ስሙ በጣም ረዥም መሆኑን ያረጋግጥልናል ማለት ነው። በተጨማሪም፣ ምንም እንኳን ይህ ችግር፣ ችግር የማያመጣ ቢመስልም፣ የአንድ ተጠቃሚ የኤመልእክት አድራሻ እርዝመት ከአብዛኞቹ ውሂበጎታወች ከፍተኛ የሆሄ ቁጥር ማለት ከ 255 በላይ ሊያልፍ የሚችልበት አጋጣሚ ግን ሊኖር ይችላል። በክፍል 6.2.4 ውስጥ ያለው የቅርጸት ማስረገጫ እንደዚህ ዓይነት ገደብን ስለማይፈጽም፣ በዚህ ክፍል ውስጥ ሁሉ ስራችን የተሟላ ይሆን ዘንድ አንድ ገደብ እናክልበታለን፡፡ ዝርዝር 6.14 የተገኙትን የፈተና ውጤቶች ያሳያል፡፡
sim
) እና የ‘ኤመልእክት (emelekt
) እርዝመትን ማስረገጫ ፈተናዎች። ቀይ test/models/teteqami_test.rb
require 'test_helper'
class TeteqamiTest < ActiveSupport::TestCase
def setup
@teteqami = Teteqami.new(sim: "Abnetawi Teteqami", emelekt: "teteqami@misalei.com")
end
.
.
.
test "ስም ረጅም መሆን የለበትም" do
@teteqami.sim = "ኤ" * 51
assert_not @teteqami.valid?
end
test "ኤመልእክት ረጅም መሆን የለበትም" do
@teteqami.emelekt = "ኤ" * 244 + "@example.com"
assert_not @teteqami.valid?
end
end
ለምቾት ሲባል፣ አንድ የ 51 ሃረግ ሆሄዎች እርዝመትን ለመስራት በዝርዝር 6.14 ላይ “የሃረግ ማባዛትን” ተጠቅመናል። ሰሌዳውን በመጠቀም እንዴት እንደሚሰራ ማየት እንችላለን:-
>> "ኤ" * 51
=> "ኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤ"
>> ("ኤ" * 51).length
=> 51
የኤመልእክት እርዝመት ማስረገጫው ከሚገባው በላይ አንድ ሆሄን በመጨመር ተቀባይነት ያለውን አንድ የኤመልእክት አድራሻ ያዘጋጃል (እዚህ ላይ የመጨረሻው የኤመልእክት አድራሻ የሆሄ እርዝመት 255 መሆን ስላለበት፣ የኤመልእክት አድራሻው የሆሄው እርዝመት 256 ከሆነ ተቀባይነት የለውም ማለት ነው):-
>> "ኤ" * 244 + "@misalei.com"
=> "ኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤ
ኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤ
ኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤ
ኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤ
ኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤኤ@misalei.com"
>> ("ኤ" * 244 + "@misalei.com").length
=> 256
በዚህ ጊዜ በዝርዝር 6.14 ውስጥ ያሉ ፈተናወች ቀይመሆን አለባቸው፡-
$ rails test
እነሱ እንዲያልፉ ለማድረግ፣ እርዝመቱን ለመገደብ የሚጠቅም የማስረገጫ ነጋሪአሴትን መጠቀም ይኖርብናል፤ ይህም በቀላሉ እርዝመት‘ን (length
)፣ የከፍተኛውን እርዝመት ወሰን ለመገደብ ከ‘ከፍተኛ (maximum
) ሰሚአሴት ጋር መጠቀም ነው (ዝርዝር 6.16)።
sim
) እና ለ‘ኤመልእክት (emelekt
) ባሕሪዎች የእርዝመት ማስረገጫዎችን ማከል። አረንጓዴ app/models/teteqami.rb
class Teteqami < ApplicationRecord
validates :sim, presence: true, length: { maximum: 50 }
validates :emelekt, presence: true, length: { maximum: 255 }
end
አሁን ፈተናወቹ አረንጓዴመሆን አለባቸው:-
$ rails test
የፈተና ስብስባችን በድጋሜ ስላለፈ፣ ወደ ከባዱ የኤመልእክት ቅርጸት ማስረገጫ መሄድ እንችላለን።
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
የ‘ስም (sim
) ባሕሪ ማስረገጫችን አነስተኛ ገደቦችን ብቻ ያስገድዳሉ (ከ 51 ሆሄዎች በታች የሆነ ማንኛውም ባዶ ያልሆነ ስምን ሳይቀር ተቀባይ ያደርገዋል) ግን በእርግጥ የ‘ኤመልእክት (emelekt
) ባሕሪው አንድ የኤመልእክት አድራሻ ብቁ ለመሆኑ በጣም ጥብቅ የሆነ መስፈርትን ማሟላት አለበት፡፡ እስካሁን ድረስ ባዶ የሆኑ የኤመልእክት አድራሻዎችን ብቻ ነጽገናል፣ በዚህ ክፍል ውስጥ፣ የኤመልእክት አድራሻውን የተለመደውን የ teteqami@misalie.com
ዓይነት ስርዓተ ይዘት እንዲያሟላ እንጠይቃለን።
ፈተናወቹም ሆኑ ማስረገጫው ሙሉ በሙሉ ሁሉንም ነገር የሚያሟሉ አይደሉም፣ በጣም ብቁ የሆኑትን የኤመልእክት አድራሻዎችን ለመቀበል እና ብቁ ያልሆኑትን ላለመቀበል ብቻ ግን በቂ ናቸው፡፡ ብቁ እና ብቁ ያልሆኑ የኤመልእክት አድራሻ ስብስቦችን በሚያሳትፉ ሁለት ፈተናወች እንጀምራለን። እነዚህን ስብስቦች ለማዘጋጀት፣ በዚህ የሰሌዳ ክፍለ ጊዜ ውስጥ እንደሚታየው፣ የሃረጎችን ድርድር ለመስራት ስለሚያስችለው ጠቃሚ %w[]
ዘዴ ማወቁ ጠቃሚ ነው:-
>> %w[asny bekele kebede]
=> ["asny", "bekele", "kebede"]
>> adrashawech = %w[TETEQAMI@asny.COM YE_TE-TEQAMI@asny.bekele.org
mejemeriya.mecheresha@asny.jp]
=> ["TETEQAMI@asny.COM", "YE_TE-TEQAMI@asny.bekele.org", "mejemeriya.mecheresha@asny.jp"]
>> adrashawech.each do |adrasha|
?> puts adrasha
>> end
TETEQAMI@asny.COM
YE_TE-TEQAMI@asny.bekele.org
mejemeriya.mecheresha@asny.jp
እዚህ ላይ የ‘እያንዳንዳቸው (each
) ዘዴን (ክፍል 4.3.2) በመጠቀም በእያንዳንዱ የ‘አድራሻወች (adrashawech
) ድርድር አባል ላይ በመደጋገም እንዴት የያንዳንዱን አባል ዋጋ ማግኘት እንደምንችል እንመለከታለን። ይህንን ብልሃት ሰንቀን አሁን አንዳንድ መሰረታዊ የኤመልእክት ቅርጸት ማስረገጫ ፈተናወችን ለመጻፍ ዝግጁውች እንሆናለን፡፡
የኤመልእክት ቅርጸት ማስረገጫ አታላይ እና ለስህተት የሚያጋልጥ ስለሆነ፣ በማስረገጫው ውስጥ ያሉ ማናቸውንም ስህተቶች ለመያዝ ፈተናወቹን ለማለፍ ብቁ የሚሆኑ የኤመልእክት አድራሻ ፈተናወችን በመፈተን እንጀምራለን፡፡ በሌላ አነጋገር የማረጋገጫ ገደቡን ካስቀመጥን በኋላም ቢሆን፣ ልክ እንደ teteqami@misalei,com ያሉ ብቁ ያልሆኑ የኤመልእክት አድራሻዎች ውድቅ ማድረጉን ብቻ ሳይሆን፣ ብቁ የሆኑ ማለት እንደ teteqami@misalei.com ያሉ ብቁ አድራሻዎችን ደግሞ ተቀባይነት እንዳላቸው ማረጋገጥ እንፈልጋለን (በአሁኑ ጊዜ ሁሉም ባዶ ያልሆኑ የኤመልእክት አድራሻዎች ብቁ ስለሆኑ ተቀባይነት አላቸው)። ብቁ የኤመልእክት አድራሻዎችን የሚወክሉ ናሙናወች በዝርዝር 6.18 ውስጥ ይገኛል፡፡
test/models/teteqami_test.rb
require 'test_helper'
class TeteqamiTest < ActiveSupport::TestCase
def setup
@teteqami = Teteqami.new(sim: "Abnetawi Teteqami", emelekt: "teteqami@misalei.com")
end
.
.
.
test "የኤመልእክት ማስረገጫ ብቁ አድራሻዎችን መቀበል አለበት" do
biku_adrashawech = %w[teteqami@misalie.com TETEQAMI@asny.COM
YE_TE-TEQAMI@asny.bekele.org
mejemeriya.mecheresha@asny.jp alice+bob@baz.cn]
biku_adrashawech.each do |biku_adrasha|
@teteqami.emelekt = biku_adrasha
assert @teteqami.valid?, "#{biku_adrashawech.inspect} ብቁ መሆን አለበት"
end
end
end
ከአንድ ብጁ የስህተት መልእክት ጋር፣ አንድ ሁለተኛ አማራጫዊ ነጋሪአሴትን ማካተታችንን ልብ በሉ፣ ይህ መልእክት እዚህ ላይ ፈተናው እንዳይሳካ የሚያደርገውን የኤመልእክት አድራሻ ይለየዋል፡-
assert @teteqami.valid?, "#{valid_address.inspect} ብቁ መሆን አለበት"
(ይህ በክፍል 4.3.3 ውስጥ የተገለጸውን፣ ውስጠገምት የተደረገውን የ‘መርምር (inspect
) ዘዴን ይጠቀማል።) ዝርዝር 6.18 ‘ን በመሰለ አሰራር ላይ፣ ማለት አንድ ፈተናን ከ‘እያንዳንዳቸው (each
) ምልልስ ጋር በመጠቀም ወቅት፣ ውድቀት የሚያስከትለውን ልዩ አድራሻ በምልልሱ ውስጥ ማካተቱ እጅግ ጠቃሚ ሲሆን፣ ያለበለዚያ ግን ማናቸውም ውድቀቶች ለሁሉም የኤመልእክት አድራሻዎች አንድ ዓይነት የሆነውን እና የችግሩ መንስኤን ለመለየት የሚያበቃውን የመስመር ቁጥርን ለይቶ ማወቅ ብቻ ይሆናል።
ቀጥሎም እንደ teteqami@misalie፣com (በነጥብ ምትክ ነጠላ ሰረዝ ሲሆን) እና teteqami_at_desta.org (የአት ‘@’ ምልክቱ አለመኖር) ላሉት ብቁ ላልሆኑ እና እንዲሁም ለተለያዩ ብቁ ላልሆኑ የኤመልእክት አድራሻወች ብቁ ያለመሆን ፈተናወችን እናክላለን፡፡ ዝርዝር 6.19 ልክ እንደ ዝርዝር 6.18 ውድቀት የሚያስከትለውን አድራሻ በትክክል ለመለየት አንድ የተበጀ የስህተት መልእክትን ያካትታል፡፡
test/models/teteqami_test.rb
require 'test_helper'
class TeteqamiTest < ActiveSupport::TestCase
def setup
@teteqami = Teteqami.new(sim: "Abnetawi Teteqami", emelekt: "teteqami@misalei.com")
end
.
.
.
test "የኤመልእክት ማስረገጫ ብቁ ያልሆኑ አድራሻዎችን መንጸግ አለበት" do
biku_yalhonu_adrashawech = %w[teteqami@misalie,com
teteqami_at_seny.org teteqami.sim@misalie.
mola@dereje_tesfaye.com belay@wesen+daniel.com]
biku_yalhonu_adrashawech.each do |biku_yalhone_adrasha|
@teteqami.emelekt = biku_yalhone_adrasha
assert_not @teteqami.valid?, "#{biku_yalhone_adrasha.inspect} ብቁ መሆን አለበት"
end
end
end
በዚህ ጊዜ ፈተናው ቀይመሆን አለበት፡-
$ rails test
የአፕልኬሽኑ ኮድ ለኤመልእክት የቅርፀት ማስረገጫ የ‘ቅርፀት (format
) ማስረገጫን ይጠቀማል፣ ይህም በዚህ መልኩ ይሰራል:-
validates :emelekt, format: { with: /<መደበኛ ሂሳበሃረግ>/ }
ይህ ከተሰጠው መደበኛ ሂሳበሃረግ (Regular Expression) (ወይም ሬጀክስ (regex)) ጋር ባሕሪውን ያስረግጣል፣ ይህም በሃረጎች ውስጥ ጥለቶችን ለማዛመድ የሚያገለግል ሃይለኛ (እና ብዙውን ጊዜ እንቆቅልሽ) የሆነ ቋንቋ ነው። ይህ ማለትም ብቁ ያልሆኑትን የኤመልእክት አድራሻዎች ሳናዛምድ፣ ብቁዎቹን የኤመልእክት አድራሻዎች ብቻ ለማዛመድ አንድ መደበኛ ሂሳበሃረግን መስራት አለብን ማለት ነው።
እርግጥ ነው በተገቢው የኤመልእክት መስፈርት መሰረት፣ አንድ ሙሉ ለሙሉ የኤመልእክት አድራሻዎችን ለማዛመድ የሚችል መደበኛ ሂሳበሃረግ አለ፣ ነገር ግን እጅግ ሰፊ፣ ግልጽ ያልሆነ እና ምናልባትም ውጤታማ11 ላይሆን የሚችል ነው፡፡ ግባችን ከተለመዱት መካከል ጥቂቶቹን ብቻ እንጅ፣ ሁሉንም የኤመልእክት አድራሻ የቅርጸት ስህተቶችን ፈልጎ ለማግኘት አይሆንም። ስለዚህ በተግባሩ ጠንካራ መሆኑን የሚያረጋግጥ እና በሁኔታው ላይ በበለጠ የሚሰራ አንድ መደበኛ ሂሳበሃረግን እንገነባለን። እሱም ይህንን ይመስላል፡-
BQUYE_EMELEKT_MEDEBGNA_HISABEHEREG = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
ይህ ከየት እንደመጣ ለመረዳት እንችል ዘንድ፣ ሰንጠረዥ 6.1 በደንብ ከፋፍሎ አቅርቦታል።12
ሂሳበሃረግ | ትርጉም |
/\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i |
የተሟላው መደበኛ ሂሳበሃረግ |
/ |
የመደበኛ ሂሳበሃረጉ መጀመሪያ |
\A |
በመጀመሪያ ላይ የሚገኝ ሃረግን ያዛምዳል |
[\w+\-.]+ |
ቢያንስ ቢያንስ አንድ የፊደል ሆሄ፣ የመደመር ምልክት፣ የሰረዝ ምልክት ወይም ነጥብ መኖር ይገባዋል |
@ |
አንድ የቃልበቃል “የአት ምልክት” መኖር ይገባዋል |
[a-z\d\-.]+ |
ቢያንስ ቢያንስ አንድ ፊደል፣ የሰረዝ ምልክት፣ ቁጥር ወይም ነጥብ መኖር ይገባዋል |
\. |
አንድ የቃልበቃል የነጥብ ምልክት መኖር ይገባዋል |
[a-z]+ |
ቢያንስ ቢያንስ አንድ ፊደል መኖር ይገባዋል |
\z |
መጨረሻ ላይ የሚገኝ አንድ ሃረግን ያዛምዳል |
/ |
የመደበኛ ሂሳበሃረጉ መጨረሻ |
i |
ለመልከፊደል-ግድየለሽ (የትንሽ እና የዓቢ የእንግሊዝኛ ፊደላትን መርሃባ ብሎ የሚቀበል) |
ሰንጠረዥ 6.1 ‘ን በማጥናት ብዙ ልትማሩ ብትችሉም፣ መደበኛ ሂሳበሃረግን በትክክል ለመረዳት አንድ እንደ ሩቡላር ያለ የመደበኛ ሂሳበሃረግ በይነተገናኝ አዛማጅን መጠቀሙን ግን ልክ እንደ አንድ አስፈላጊ ነገር አድርጌ እቆጥረዋለሁ (ምስል 6.8)፡፡13 የሩቡላር የድርጣቢያ መደበኛ ሂሳበሃረግን ለማዘጋጀት አንድ የሚያምር የበይነተገናኝ ገጽታን፣ ከአንድ ምቹ ቀልጣፋ ማጣቀሻ ጋር ያካተተ ነው፡፡ ሰንጠረዥ 6.1 ‘ን አንድ ለሩቡላር አሳሽ በተከፈተ መስኮት ላይ እንድታጠኑት አሳስባችኋለሁ፣ ይሄ ነው ከተባለ በላይ ስለ መደበኛ ሂሳበሃረግ ማንበቡ፣ እነሱን በበይነተገናኝ አካል ላይ የመሞከርን ያህል ሊተካ አይችልም፡፡ (ማሳሰቢያ:- በሩቡላር ውስጥ በሰንጠረዥ 6.1 ያለውን መደበኛ ሂሳበሃረግ የምትጠቀሙ ከሆነ፣ በአንድ የተሰጠ የፈተና ሃረግ ውስጥ በአንድ ጊዜ ከአንድ በላይ የኤመልእክት አድራሻን ማዛመድ ትችሉ ዘንድ፣ የ \A
እና \z
ሆሄወችን አውጥታችሁ እንድትማሩ ከወዲሁ እመክራለሁ፡፡ በተጨማሪም መደበኛ ሂሳበሃረጉ አነዚህን /.../
ሆሄወች በውስጡ ያካተተ መሆኑን ልብ በሉ፤ ስለዚህ ሩቡላርን በምትጠቀሙበት ጊዜ እነሱን ማስወገድ እንደሚኖርባችሁ አስተውሉ።)
ለ‘ኤመልእክት (emelekt
) ቅርጸት ማረጋገጫ ከሰንጠረዥ 6.1 መደበኛ ሂሳበሃረጉን ተግባር ላይ ማዋሉ በዝርዝር 6.21 ውስጥ ያለውን ኮድ ይሰጣል።
app/models/teteqami.rb
class Teteqami < ApplicationRecord
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 }
end
እዚህ ላይ የመደበኛ ሂሳበሃረጉ ማለት ብቁ_የኤመልእክት_መደበኛ_ሂሳበሃረግ (BIKU_YE_EMELEKT_MEDEBEGNA_HISABEHEREG
) አንድ ቋሚ ተላዋዋጪ ነው፤ ይህም በዓብይ ፊደል የሚጀምር አንድ ስም በሩቢ ውስጥ አንድ ቋሚ ተላዋዋጪ እንደሆነ ያመለክታል፡፡ ኮዱ ከ:-
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 }
ጥለት ጋር የሚዛመዱትን የኤመልእክት አድራሻዎች ብቻ ብቁ እንደሆኑ አድርጎ ይቆጥራል። (ከዚህ በላይ ያለው ሂሳበሃረግ አንድ አነስተኛ ድክመት አለው፣ እንደ abrham@chuchu..com
ያለ ተከታታይ ነጥቦች የያዘ ብቁ ያልሆነ አድራሻን ያስተናግዳል፡፡ ይህንን ጉድለት ለማስተካከል በዝርዝር 6.21 ውስጥ ያለውን መደበኛ ሂሳበሃረግን የማዘመኑ ጉዳይ፣ ልክ እንደ አንድ መልመጃ ይሆን ዘንድ ለናንተ ተትቷል (ክፍል 6.2.4.1))፡፡
በዚህ ጊዜ ፈተናው አረንጓዴመሆን አለበት፡-
$ rails test:models
ይህ ማለትም አንድ ገደብ ብቻ ይቀራል ማለት ነው፤ እሱም የኤመልእክት ልዩነትን ማስገደድ ይሆናል፡፡
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
app/models/teteqami.rb
class Teteqami < ApplicationRecord
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 }
end
የኤመልእክት አድራሻዎች ልዩነትን ለማስገደድ (እናም ልክ እንደ የተጠቃሚስሞች አድርገን ልንጠቀምባቸው እንችል ዘንድ) የ‘፡ልዩነት (:uniqueness
) አማራጪን በ‘አስረግጥ (validates
) ዘዴ ላይ እንጠቀማለን፡፡ እዚህ ላይ ግን አንድ የሚያስፈልግ ልዩ መስፈርት ስላለ ይህንን ክፍል ሳትዘሉ በጥንቃቄ እንድታነቡት አስጠነቅቃችኋለሁ።
በአንዳንድ አጪር ፈተናወች እንጀምራለን፡፡ ባለፈው የቅርጸት ፈተናችን ውስጥ አብዛኛውን ጊዜ አዲስ.ተጠቃሚ‘ን (Teteqami.new
) ተጠቅመን ነበረ፣ ይህም በማህደረ-ትውስታ ውስጥ አንድ የሩቢ ቁስን ይፈጥራል፣ የልዪነት ፈተኖችን ለመፈተን ግን መዝገቡን በውሂበጎታ14 ውስጥ ማስቀመጥ ይኖርብናል። የመጀመሪያው የተደጋገመ የኤመልእክት ፈተና በዝርዝር 6.24 ውስጥ ይታያል (እዚህ ላይ፣ የተደጋገመ ማለት በሁለመናው ጪራሽ አንድ የሆነ ማለት ነው)፡፡
test/models/teteqami_test.rb
require 'test_helper'
class TeteqamiTest < ActiveSupport::TestCase
def setup
@teteqami = Teteqami.new(sim: "Abnetawi Teteqami", emelekt: "teteqami@misalei.com")
end
.
.
.
test "የኤመልእክት አድራሻዎች ልዩ መሆን አለባቸው" do
yetedegageme_teteqami = @teteqami.dup
@teteqami.save
assert_not yetedegageme_teteqami.valid?
end
end
እዚህ ላይ ያለው ዘዴ @ተጠቃሚ.ተደጋጋሚ‘ን (@teteqami.dup
) በመጠቀም ከ‘@ተጠቃሚ (@teteqami
) ጋር አንድ አይነት የኤመልእክት አድራሻ ያለው አንድ ተጠቃሚን መስራት ነው፣ ይህም አንድ የተደጋገመ ተጠቃሚን ከአንድ አይነት ባሕሪዎች ጋር ይፈጥራል። ከዚያ @ተጠቃሚን (@teteqami
) በውሂበጎታ ውስጥ የምናስቀምጥ ስለሆነ፣ የተደጋገመው ተጠቃሚ ቀድሞውኑ በውሂበጎታው ውስጥ የተፈጠረ አንድ የኤመልእክት አድራሻ ይኖረዋል፣ ስለሆነም የኤመልእክት አድራሻው ብቁ መሆን አይገባውም።
በዝርዝር 6.24 ላይ እንደሚታየው፣ ልዩነት፡ እውነት (uniqueness: true
) ዘዴን የ‘ኤመልእክት (emelekt
) ማስረገጫ ላይ በማከል በዝርዝር 6.25 ውስጥ ያለውን አዲሱን ፈተና ማሳለፍ እንችላለን፡፡
app/models/teteqami.rb
class Teteqami < ApplicationRecord
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
end
ይህም ሆኖ ግን እስከአሁን አልጨረስንም፡፡ የኤመልእክት አድራሻዎች በመደበኛነት ለመልከፊደል-ግድየለሽ (Case Insensitive) እንደሆኑ ተደርገው ይካሄዳሉ፤ ማለትም eden@nega.com
ከ‘ EDEN@NEGA.COM
ወይም ከ‘ EdEN@NEga.coM
ጋር አንድ ዓይነት እንደሆነ ተደርጎ ይስተናገዳል፤ ስለዚህ ማረጋገጫችን ይህንንም በግምት ውስጥ ማስገባት ይኖርበታል ማለት ነው፡፡15 እናም የመልከፊደል-ግድየለሽነትን መፈተኑ አስፈላጊ ስለሆነ፣ ፈተናውን የምናካሂደው በዝርዝር 6.26 ላይ ባለው ኮድ ይሆናል፡፡
test/models/teteqami_test.rb
require 'test_helper'
class TeteqamiTest < ActiveSupport::TestCase
def setup
@teteqami = Teteqami.new(sim: "Abnetawi Teteqami", emelekt: "teteqami@misalei.com")
end
.
.
.
test "የኤመልእክት አድራሻዎች ልዩ መሆን አለባቸው" do
yetedegageme_teteqami = @teteqami.dup
yetedegageme_teteqami.emelekt = @teteqami.emelekt.upcase
@teteqami.save
assert_not yetedegageme_teteqami.valid?
end
end
እዚህ ላይ፣ በሃረጎች ላይ አንድ የ‘ዓቢ-ፊደል (upcase
) ዘዴን እየተጠቀምን ነው (በክፍል 4.3.2 ውስጥ ባጪሩ ተገልጿል)፡፡ ይህ ፈተና ከመጀመሪያው የተደጋገመ የኤመልእክት አድራሻ ፈተና ጋር ተመሳሳይ ፈተናን ቢያደርግም፣ እዚህ ፈተና ላይ ግን በአብይ ፊደላት የተጻፉ የኤመልእክት አድራሻዎችን ብቻ ይፈትናል። ይህ ፈተና ትንሽ ጠጠር ያለ ሆኖ ካገኛችሁት ወደ ሰሌዳችሁ ጎራ በሉ:-
$ rails console --sandbox
>> ተጠቃሚ = Teteqami.create(sim: "Abnetawi Teteqami", emelekt: "teteqami@misalei.com")
>> ተጠቃሚ.emelekt.upcase
=> "TETEQAMI@MISALEI.COM"
>> yetedegageme_teteqami = ተጠቃሚ.dup
>> yetedegageme_teteqami.emelekt = ተጠቃሚ.emelekt.upcase
>> yetedegageme_teteqami.valid?
=> true
በእርግጥ የ‘ተደጋገመ_ተጠቃሚ.ብቁነውን? (yetedegageme_teteqami.valid?
) የልዩነት ማስረገጫ መልከፊደል-ግድየለሽ ስለሆነ፣ በአሁኑ ጊዜ የሚሰጠን መልስ እውነት (true
) ይሆናል፣ ነገር ግን እኛ ሃሰት (false
) እንዲሆን እንፈልጋለን። እንደ እድል ሆኖ ፡ልዩነት (:uniqueness
) ለዚህ ስራ ሲባል አንድ የ‘መልከፊደል-ግድየለሽ (:case_sensitive
) ምርጫን ይቀበላል (ዝርዝር 6.27)፡፡
app/models/teteqami.rb
class Teteqami < ApplicationRecord
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: { case_sensitive: false }
end
በዝርዝር 6.25 ውስጥ ያለውን እውነት (true
) ዝርዝር 6.27 ውስጥ በ‘መልከፊደል-ግድየለሽ: ሃሰት (case_sensitive: false
) እንደተካነው አስተውሉ፡፡ (ሬይልስም ፡ልዩነት (:uniqueness
) እውነት (true
) እንደሆነ ከሁኔታው ይረዳል፡፡)
በዚህ ጊዜ አፕልኬሽናችን (ከአንድ ጠቃሚ ማስጠንቀቂያ ጋር) የኤመልእክት ልዩነትን ያስፈጽማል እናም የፈተና ስብስባችን ማለፍ አለበት:-
$ rails test
እዚህ ጋር አንድ ትንሽ ችግር አለ፤ ይህም የንቅ መዝገብ ልዩነት ማስረገጫ በውሂበጎታው ውስጥ ያለው ውሂብ ልዩ ለመሆኑ አንዳችም ዋስትና አይሰጥም። ምክንያቱን የሚያብራራ አንድ አጋጣሚ እነሆ:-
ከላይ ያለው ቅደም ተከተል የማያጋጥም ይመልሳል አይደል? እመኑኝ ያጋጥማል፤ በጣም ብዙ ተገልጋይ ባላቸው በማንኛውም የሬይልስ ድረጣቢያ ላይ ሊከሰት ይችላል (ይሄንን እኔ በአንድ ወቅት ትልቅ አበሳ ከፍየ ነበር የተማርኩት)፡፡ እንደ አጋጣሚ ሆኖ ግን መፍትሄውን ተግበር ላይ ማዋሉ በጣም ቀላል ነው፣ ይህም በውሂበጎታው እና በቅርጸቱ ላይ ልዩነትን ማስገደድ ብቻ ይኖርብናል፣ ዘዴያችንም በኤመልእክት አምድ (ሳጥን 6.2) ላይ አንድ የውሂበጎታ መረጃ-ጠቋሚን (Index) መፍጠር እና ከዚያ መረጃ-ጠቋሚው ልዩ እንዲሆን ማድረግ ይሆናል፡፡
በአንድ ውሂበጎታ ውስጥ አንድ አምድን በምንፈጥርበት ጊዜ፣ በዚያ አምድ መሰረት መዝገቦችን እንፈልግ እንደሆነ ማጤኑ አስፈላጊ ነው። ለምሳሌ;- በዝርዝር 6.2 ውስጥ በፍልሰት የተፈጠረውን የኤመልእክት
ባሕሪ ተመልከቱ፡፡ ከምዕራፍ 7 ጀምሮ ተጠቃሚዎች ወደ ማሳያ አፕልኬሽኑ እንዲገቡ ስንፈቅድ ከተረከበው የኤመልእክት አድራሻ ጋር የሚዛመደውን የተጠቃሚ መዝገብ መፈለግ ይኖርብናል፡፡ አለመታደል ሆኖ በገራገሩ የውሂብ ቅርጸት ላይ በመመርኮዝ፣ አንድ ተጠቃሚን በኤመልእክት አድራሻ ለመፈለግ ብቸኛው መንገድ በውሂበጎታው ውስጥ ያሉትን እያንዳንዱን የተጠቃሚ ረድፍ በመመልከት የኤመልእክት ባሕሪውን ከተሰጠው የኤመልእክት አድራሻ ጋር ማነጻጸር ነው። ይህ ማለት እያንዳንዱን ረድፍ አንድ ባንድ መመርመር አለብን ማለት ነው (ምክንያቱም ተጠቃሚው በውሂበጎታው ውስጥ የመጨረሻው ምዝግብ ሊሆን ይችላል)። ይህ በውሂበጎታ ዓለም ውስጥ የሙሉ-ሰንጠረዥ ቅኝት (Full-table Scan) በመባል ይታወቃል፣ እና ይህም በሽዎች የሚቆጠሩ ተጠቃሚዎች ላሉት አንድ ጣቢያ አንድ መጥፎ ነገር ይሆናል፡፡
በኤመልእክት አምድ ላይ አንድ የመረጃ-ጠቋሚን ማድረጉ ችግሩን ያስወግዳል፡፡ የአንድ ውሂበጎታ መረጃ-ጠቋሚን ለመረዳት፣ እሱን ከአንድ የመጽሐፍ ማውጫ ጋር አነጻጽሮ ማየቱ ጠቃሚ ነው፡፡ እንበል በአንድ መጽሐፍ ውስጥ አንድ “ተዋበች” የሚል ሆሄን ትፈልጋላችሁ እንበል። የዚህን ሆሄ ክስተቶች ለማግኘት፣ መጽሐፉ ውስጥ ያሉትን ግጾች በሙሉ አንድ ባንድ መቃኘት ይኖርባችኋል ማለት ነው፤ ይህም የወረቀት የሙሉ-ሰንጠረዥ ቅኝትን አደረጋችሁ እንደማለት ነው፡፡ በሌላ በኩል በመጽሐፉ ውስጥ “ተዋበች” የሚለውን ሆሄ የያዙ ሁሉንም ገጾች ለመመልከት፣ በመጽሐፉ ማውጫ ላይ “ተዋበች” ን በቀላሉ መፈለግ ትችላላችሁ፡፡ አንድ የውሂበጎታ መረጃ-ጠቋሚም በመሰረቱ በተመሳሳይ መንገድ ይሰራል፡፡
የኤመልእክት መረጃ-ጠቋሚው ለውሂብ መቀረጪያ መስፈርታችን አንድ አዲስ ጪማሬ ነው፣ ይህም በሬይልስ ውስጥ ፍልሰቶችን በመጠቀም ይስተናገዳል (በክፍል 6.1.1 ላይ እንደተገለጸው)፡፡ በክፍል 6.1.1 ላይ፣ የተጠቃሚ ቅርጸቱ አንድ አዲስ ፍልሰትን በራስሰር እንደፈጠረ ተመልክተናል (ዝርዝር 6.2)፡፡ አሁን ባለው ሁኔታ ላይ ግን ካሁን በፊት በነበረ አንድ ቅርጸት ላይ መዋቅርን እያከልን ስለሆነ፣ የ‘ፍልሰት (migration
) አመንጪን በመጠቀም አንድ ፍልሰትን በቀጥታ መፍጠር ይኖርብናል:-
$ rails generate migration mereja_tequami_mechemer_to_teteqamis_emelekt
የኤመልእክት ልዩነት ፍልሰቱ ልክ እንደ ተጠቃሚዎች ፍልሰት ቀድሞ የተበየነ ስላልሆነ፣ ይዘቱን ከዝርዝር 6.29 ቀድተን መገልበጥ ይኖርብናል፡፡16
db/migrate/[ማህተመጊዜ]_mereja_teequami_mechemer_to_teteqamis_emelekt.rb
class MerejaTequamiMechemerToTeteqamisEmelekt < ActiveRecord::Migration[6.0]
def change
add_index :teteqamis, :emelekt, unique: true
end
end
ይህ በ‘ተጠቃሚዎች (teteqamis
) ሰንጠረዥ የ‘ኤመልእክት (emelekt
) አምድ ላይ አንድ መረጃ-ጠቋሚ ለማከል፣ አንድ መረጃ-ጠቋሚ_አክል (add_index
) የተባለ የሬይልስ ዘዴን ይጠቀማል፡፡ መረጃ-ጠቋሚው በራሱ ልዩነትን አያስገድድም፣ ልዩነት: እውነት (unique: true
) የተባለው አማራጪ ግን ልዩነትን ያስገድዳል።
የመጨረሻው ሂደት ውሂበጎታውን ማፍለስ ነው:-
$ rails db:migrate
(እዚህ ላይ ፍልሰቱ ካልተሳካ፣ ከማንኛውም የሚሄድ የአሸዋሳጥን ሰሌዳ ክፍለ ጊዜ መውጣታችሁን አረጋግጡ፣ የአሸዋሳጥን ሰሌዳው ውሂበጎታውን ሊዘጋ እና ፍልሰቶችን ሊከላከል ይችላል።)
በዚህ ጊዜ እቃዎች (fixtures) በተባለው ፋይል ውስጥ ያለው አንድ የልዩነት ገደብ በመጣሱ ምክንያት የፈተና ስብስቡ ቀይ መሆን አለበት፣ የእቃዎች (fixtures) ፋይሉ ለፈተና ውሂበጎታው የሚያገለግሉ የናሙና ውሂቦችን ይይዛል። የተጠቃሚ እቃዎች በዝርዝር 6.1 ውስጥ በራስሰር የመነጨ ሲሆን፣ በዝርዝር 6.30 ላይ እንደሚታየው የኤመልእክት አድራሻዎቹ ልዩ አይደሉም፡፡ (ብቁወችም አይደሉም፣ ግን’ኮ የእቃዎች ውሂብ በማስረገጫዎች ውስጥ ፈጽሞ አያልፍም።)
test/fixtures/teteqami.yml
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/
# FixtureSet.html
one:
sim: MyString
emelekt: MyString
two:
sim: MyString
emelekt: MyString
እስከ ምዕራፍ 8 ድረስ እቃዎች ስለማያስፈልጉን፣ ለአሁኑ እነሱን አስወግደን ፊክስቸርስ የተባለውን ፋይል ባዶውን እንተወዋለን (ዝርዝር 6.31)።
test/fixtures/users.yml
# ባዶ
እያንዳንዱ የኤመልእክት አድራሻ ልዩ ለመሆኑ የሚያስፈልገውን መስፈርት ካሟላን በኋላም፣ በኤመልእክት ልዩነት ላይ እርግጠኛ ለመሆን አሁንም አንድ ማድረግ ያለብን ተጨማሪ ለውጥ አለ፡፡ አንዳንድ የውሂበጎታ አያያዥ ፕሮግራሞች፣ መልከፊደል-ግድየለሽ መረጃ-ጠቋሚዎችን ይጠቀማሉ። በዚህ ምክንያትም፣ “Girmeso@MiSALie.CoM” የሚለው የኤመልእክት አድራሻን፣ እና “girmeso@misalie.com” የሚለው የኤመልእክት አድራሻን፣ ልክ እንደ ሁለት የተለያየ የኤመልእክት አድራሻ አድርገው ያስተናግዱታል። የኛ አፕልኬሽን ግን እነዚህን አድራሻወች ልክ እንደ አንድ አድራሻ አድርጎ ያስተናግዳቸዋል። እናም ይህንን አለመጣጣም ለማስወገድ፣ ማንኛውንም የኤመልእክት አድራሻ ውሂበጎታው ላይ ከማስቀመጣችን በፊት የኤመልእክት አድራሻውን ከ:- “Girmeso@MiSALie.CoM” ወደ:- “girmeso@misalie.com” በመለወጥ ሁሉንም አድራሻዎች የንዑስ-ፊደል አድራሻ መስፈርት እንዲኖራቸው እናደርጋለን፡፡ ይህንን የምናደርግበት መንገድም መልሰጥሪ (Callback) ይባላል፣ ይህም በንቅ መዝገብ ቁስ ክፍለ ጊዜ በአንድ የተለየ ሁኔታ ላይ የሚጠራ ዘዴ ነው፡፡
አሁን ባለው ሁኔታ ላይ፣ ያ የተለየ ሁኔታ ቁሱ ከመቀመጡ በፊት ስለሆነ፣ ተጠቃሚውን ወደ ውሂበጎታ ላይ ከማስቀመጣችን በፊት የኤመልእክት ባሕሪውን ወደ ንዑስ-ፊደላት ለመቀየር የ‘ከማስቀመጥ_በፊት (before_save
) መልስጥሪን መጠቀም ይሆናል።17 ውጤቱም በዝርዝር 6.32 ውስጥ ይታያል፡፡ (እዚህ ላይ የመጀመሪያውን ትግበራ ለመተግበር የ‘ከማስቀመጥ_በፊት (before_save
) መልስጥሪን ተጠቅመናል፣ በክፍል 11.1 ላይ መልሰጥሪን ለመበየን የተመረጠውን ዘዴ አጣቅሴ (Method Reference) ተብሎ የሚጠራውን የተለመደ ዘዴ በምንጠቀምበት ወቅት ይህንን ጉዳይ በድጋሜ እንወያይበታለን።)
app/models/teteqami.rb
class Teteqami < ApplicationRecord
before_save { self.emelekt = emelekt.downcase }
validates :sim, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :emelekt, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: true
end
በዝርዝር 6.32 ውስጥ ያለው ኮድ አንድ ጥምርን ወደ ከማስቀመጥ_በፊት (before_save
) መልሰጥሪ ያሳልፍ እና የተጠቃሚውን የኤመልእክት አድራሻ፣ የሃረግ ንዑስ-ፊደል (downcase
) ዘዴን በመጠቀም፣ አንድ ወቅታዊ የንዑስ-ፊደላት ስሪት ዋጋን ያዘጋጃል፡፡
ሁሉም የኤመልእክቶች መልከፊደል-ግድየለሽ ከሆኑ ከንዑስ-ፊደላት ጋር በሚዛመድ መልኩ በጥሩ ሁኔታ ስለሚሰራ ዝርዝር 6.32 የ‘ልዩነት (uniqueness
) ገደብን ወደ እውነት (true
) እንደሚመልሰው ልታስተውሉ ይገባል፡፡ ብዙ የውሂበጎታወች አንድ መረጃ-ጠቋሚን ተጠቅሞ ከአንድ መልከፊደል-ግድየለሽ ተዛማጅ ጋር ለማጣመር አስቸጋሪ ስለሚሆንባቸው፣ ይህ አሰራር በእርግጥ፣ የዝርዝር 6.29 የውሂበጎታ መረጃ-ጠቋሚን ከመተግበር ጋር የተያያዙ ችግሮችን ይከላከላል፡፡18
የመጀመሪያ ገደቡን ወደ ነበረበት መመለስ፣ በዝርዝር 6.26 ውስጥ ያለውን ፈተና ይሰብረዋል፣ ካሁን በፊት የነበረውን የዝርዝር 6.24 ፈተና ኮድን መልሶ በመጠቀም ግን ፈተናው በቀላሉ እንዲያልፍ ማድረግ ይቻላል፣ እናም ይህ የፈተና ኮድ በድጋሜ፣ በዝርዝር 6.33 ላይ ተጽፎ ቀርቧል፡፡
test/models/teteqami_test.rb
require 'test_helper'
class TeteqamiTest < ActiveSupport::TestCase
def setup
@teteqami = Teteqami.new(sim: "Abnetawi Teteqami", emelekt: "teteqami@misalei.com")
end
.
.
.
test "የኤመልእክት አድራሻዎች ልዩ መሆን አለባቸው" do
yetedegageme_teteqami = @teteqami.dup
@teteqami.save
assert_not yetedegageme_teteqami.valid?
end
end
በነገራችን ላይ፣ በዝርዝር 6.32 ውስጥ ያለውን ምደባ እንደዚህ አድርገን መጻፍ እንችል ነበር:-
self.emelekt = self.emelekt.downcase
(ራሥ (self
) የአሁኑ ተጠቃሚን በሚያመለክትበት ጊዜ) በተጠቃሚ ቅርጸቱ ውስጥ የራሥ (self
) ቁልፍቃሉ ከይሆናል ምልክቱ በስቀኝ በኩል ከሆነ ግን እሱን መጠቀሙ እና አለመጠቀሙ ምርጫዊ ይሆናል:-
self.emelekt = emelekt.downcase
በ‘ አንሶላ
ዘዴ (ክፍል 4.4.2) ውስጥ በ‘አገላብጥ (reverse
) አውድ ውስጥ ይህንን ሃሳብ በግልጽ ተመልክተናል፤ ማለት ራሥ (self
) አንድ ተለዋዋጪን በመመደብ ወቅት አማራጫዊ እንዳልሆነም አስተውለናል፣ ስለዚህ:-
emelekt = emelekt.downcase
አይሰራም፡፡ (ይህንን ጉዳይ በክፍል 9.1 ውስጥ በሰፊው እንወያይበታለን፡፡)
በዚህ ጊዜ፣ ከዚህ በፊት በተወልደ ላይ የተከሰተው አጋጣሚ በተገቢው ሁኔታ እንደሚሰራ እንመልከት:- በመጀመሪያው የምዝገባ መጠይቅ መሰረት፣ የውሂበጎታው የተጠቃሚውን መዝገብ ያስቀምጥ እና የሁለተኛው መጠይቅ የተደጋገመ የኤመልእክት አድራሻ ልዩነት ገደብን ስለሚጥስ፣ የውሂበጎታው የተጠቃሚውን መዝገብ እንዳይቀመጥ ውድቅ ያደርገዋል፡፡ (በዚህ ሁኔታ ላይ አንድ ስህተት በሬይልስ ዘገባ ውስጥ ሊታይ ይችላል፣ ነገር ግን ያ ምንም ዓይነት ጉዳት አያደርስም፡፡) በተጨማሪም፣ ይህንን የመረጃ-ጠቋሚ በኤመልእክት ባሕሪ ውስጥ ማከሉ፣ በክፍል 6.1.4 ውስጥ በግልጽ እንደተጠቀሰው አንድ ሁለተኛ ግብን ያከናውናል፤ በሳጥን 6.2 ላይ እንደተጠቀሰው፣ በ‘ኤመልእክት (emelekt
) ባሕሪ ላይ ያለው የመረጃ-ጠቋሚ፣ ተጠቃሚዎችን በኤመልእክት አድራሻ ሲፈልጉ፣ የሙሉ-ሰንጠረዥ ቅኝትን በመከላከል፣ የመቀልጠፍ አቅም ችግርን ያስተካክላል፡፡
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
reload
) ዘዴን እና እኩልነትን ለመፈተሽ ደግሞ የ‘እኩልነት_አረጋግጥ (assert_equal
) ዘዴን ይጠቀማል። ዝርዝር 6.34 ላይ ያለው ፈተና፣ ትክክለኛውን ነገር መፈተኑን ለማረጋገጥ፣ የ‘ከማስቀመጥ_በፊት (before_save
) መልሰጥሪ ላይ አስተያየት በማድረግ ፈተናው ቀይመሆኑን አረጋግጡ፣ ከዚያ አስተያየቱን በማስወገድ ፈተናው ወደነበረበት አረንጓዴመመለሱን ደግማችሁ አረጋግጡ፡፡
emelekt
) ባሕሪውን በቀጥታ ለማሻሻል፣ የ “አናጋ” ዘዴን emelekt.downcase!
በመጠቀም መጻፍ መቻሉን የፈተና ስብስቡን በማስኬድ አረጋግጡ።
test/models/teteqami_test.rb
require 'test_helper'
class TeteqamiTest < ActiveSupport::TestCase
def setup
@teteqami = Teteqami.new(sim: "Abnetawi Teteqami", emelekt: "teteqami@misalei.com")
end
.
.
.
test "የኤመልእክት አድራሻዎች ልዩ መሆን አለባቸው" do
yetedegageme_teteqami = @teteqami.dup
@teteqami.save
assert_not yetedegageme_teteqami.valid?
end
test "የኤመልእክት አድራሻዎች በንዑስ-ፊደል መቀመጥ አለባቸው" do
deblaqa_melkefidel_emelekt = "Beyene@MiSALie.CoM"
@teteqami.emelekt = deblaqa_melkefidel_emelekt
@teteqami.save
assert_equal deblaqa_melkefidel_emelekt.downcase, @teteqami.reload.emelekt
end
end
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
end
ለስም እና ለኤመልእክት መስኮች ማስረገጫዎችን ስለበየንን፣ አሁን ከተጠቃሚ ባሕሪወች፣ የመጨረሻና መሰረታዊ የሆነውን፣ አንድ ጥብቅ የመሕለፈቃል አምድን ለማከል ዝግጁ ነን፡፡ ዘዴው እያንዳንዱ ተጠቃሚ አንድ መሕለፈቃል እና አንድ የመሕለፈቃል ማረጋገጫ እንዲኖረው ይጠይቃል፣ ከዚያም የተከተፈውን (hashed) መሕለፈቃል ውሂበጎታው ውስጥ ያስቀምጣል። (እዚህ ላይ አንድ ግራ የሚያጋባ ነገር ሊኖር ይችላል፡፡ በአሁኑ ዓውድ ውስጥ hash በክፍል 4.3.3 የሚገኘውን የሩቢ ፕሮግራም የውሂብ መዋቅር የሚያጣቅስ ሳይሆን፣ በተሰጠው ውሂብ ላይ ፈጽሞ ወደ ነበረበት ሊመለስ የማይችል አንድ የመክተፍ ሥልት (hash function) ውጤትን ነው፡፡) እንዲሁም፣ በአንድ የተሰጠ መሕለፈቃል ላይ በመመርኮዝ አንድ ተጠቃሚን ለማረጋግጥ የሚያስችል አንድ መንገድን እናክላለን፣ ይህንንም በምዕራፍ 8 ላይ ተጠቃሚዎችን ወደ ጣቢያው መግባት እንዲፈቅድላቸው የምንጠቀምበት ዘዴ ይሆናል፡፡
ተጠቃሚዎችን የማረጋገጫ ዘዴው፣ አንድ ርክብ መሕለፈቃልን መውሰድ፣ ከዚያ እሱኑ መክተፍ፣ እና ውጤቱን ውሂበጎታ ውስጥ ካለው ክትፍ ዋጋ ጋር ማነጻጸር እና ሁለቱ ክትፎች ከተዛመዱ፣ የተረከበው መሕለፈቃል ትክክል እና ተጠቃሚው ደግሞ የተረጋገጠ ይሆናል። ከጥሬ መሕለፈቃሎች ይልቅ፣ የተከተፈ ዋጋቸውን በማነጻጸር፣ መሕለፈቃሎቹን ውሂበጎታው ላይ ሳናስቀምጥ ተጠቃሚዎችን ማረጋገጥ እንችላለን፡፡ ይህ ማለት አጋጣሚ ሁኖ የውሂበጎታችን ቢጠለፍ እንኳ፣ የተጠቃሚዎቻችን መሕለፈቃሎች አሁንም ቢሆን ጥብቆች ናቸው ማለት ነው።
በጣም ጥብቁ የመሕለፈቃል ፋብሪካው የሚተገበረው ጥብቅ_መሕለፈቃል_አለው (has_secure_password
) ተብሎ የሚጠራውን አንድ ነጠላ የሬይልስ ዘዴን በመጠቀም ነው፣ ይህንንም እንደሚከተለው አድርገን በተጠቃሚ ቅርጸቱ ውስጥ ማካተት እንችላለን:-
class Teteqami < ApplicationRecord
.
.
.
has_secure_password
end
ከላይ እንደሚታየው ዘዴውን በአንድ ቅርጸት ውስጥ በምናካትትበት ጊዜ፣ ይህ ዘዴ የሚከተሉትን ተግባራት ያክላል፡-
password_digest
) ባሕሪ ላይ አንድ በጥብቅ የተከተፈ ውጤትን የማስቀመጥ ችሎታን፣
password
እና የመሕለፈቃል ማረጋገጫ password_confirmation
)፣ ቁሱ በሚፈጠርበት ጊዜ የመሕለፈቃል እና የመሕለፈቃል ማረጋገጫ መኖርን ማረጋገጥ እና፣ መሕለፈቃሉና የመሕለፈቃል ማረጋገጫው መዛመዱን ማስረገጥን፣
false
) የሚመልስ አንድ የ‘አረጋግጥ (authenticate
) ዘዴን ያክላል።
ጥብቅ_መሕለፈቃል_አለው (has_secure_password
) አስማቱን እንዲሰራ ለማድረግ ብቸኛው መስፈርት፣ ተዛማጅ ቅርጸቱ አንድ መሕለፈቃል_ፈጪ (password_digest
) የተባለ ባሕሪ እንዲኖረው ማድረግ ብቻ ነው። (ፍጪ (Digest) የሚለው ስም ከስነ መሰውራዊ መክተፍ ተግባሮች የመጣ የስያሜ ቃል ነው። በዚህ አውድ ውስጥ የተከተፈ መሕለፈቃል እና ፍጪ መሕለፈቃል ሁለቱንም አንድ ዓይነት አባባሎች ናቸው፡፡)20
የተጠቃሚ ቅርጸቱን በርተመለከተ፣ በምስል 6.9 ላይ የሚታየውን የውሂብ ንድፍ መተግበርን ይጠይቃል፡፡
በምስል 6.9 ላይ የተመለከተውን፣ የውሂብ ቅርጸት ለመተግበር በመጀመሪያ ለ‘መሕለፈቃል_ፈጪ (password_digest
) አምድ አንድ ተገቢ ፍልሰትን እናመነጫለን፡፡ በዚህ ሁኔታ ላይ ሬይልስ የ‘ተጠቃሚዎች teteqamis
ሰንጠረዥ ላይ ዓምዶችን ለማከል አንድ ፍልሰትን በራስሰር እንዲገነባ፣ የፍልሰት ስሙን በ‘ለ_ተጠቃሚዎች (to_teteqamis
) መጨረሱ አመች ይሆናል፣ ነገር ግን የፈለግነውን ማንኛውንም የፍልሰት ስም መምረጥ እንችላለን። ውጤቱ ለተጠቃሚወች_መሕለፈቃል_ፈጪ_አክል (mehlefekal_fech_akl_to_teteqamis
) ከሚለው የፍልሰት ስሙ ጋር እንደሚከተለው ይታያል፡-
$ rails generate migration mehlefekal_fech_akl_to_teteqamis password_digest:string
እዚህ ጋር ደግሞ መፍጠር የምንፈልገውን የስም እና የባሕሪውን ዓይነት ከ‘መሕለፈቃል_ፈጪ:ሃረግ (password_digest:string
) ነጋሪአሴት ጋር አቅርበናል፡፡ (ይህንን በዝርዝር 6.1 ውስጥ መጀመሪያ ከመነጨው እና የ‘ስም:ሃረግ (sim:string
) እና የ‘ኤመልእክት:ሃረግ (emelekt:string
) ነጋሪአሴቶችን ካካተተው የተጠቃሚዎች (teteqamis
) ሰንጠረዥ ጋር አነጻጽሩ፡፡) በዝርዝር 6.36 ውስጥ እንደሚታየው፣ መሕለፈቃል_ፈጪ:ሃረግ‘ን (password_digest:string
) በማካተት፣ ሬይልስ ሙሉውን ፍልሰት እንዲገነባልን በቂ መረጃ ሰጥተነዋል።
password_digest
) አምድን የሚያክል ፍልሰት። db/migrate/[ማህተመጊዜ]_mehlefekal_fech_akl_to_teteqamis.rb
class MehlefekalFechAklToTeteqamis < ActiveRecord::Migration[6.0]
def change
add_column :teteqamis, :password_digest, :string
end
end
ዝርዝር 6.36 አንድ የ‘መሕለፈቃል_ፈጪ (password_digest
)አምድን ወደ ተጠቃሚዎች (teteqamis
) ሰንጠረዥ ለማከል የ‘አምድ_አክል (add_column
) ዘዴን ይጠቀማል፡፡ ይህንን አምድ ውሂበጎታው ላይ ለመፍጠር፣ በቃ ውሂበጎታውን እንደሚከተው አድርገን እናፈልሳለን:-
$ rails db:migrate
ፍጪ መሕለፈቃሉን ለመስራት ጥብቅ_መሕለፈቃል_አለው (has_secure_password
) ቢክሪፕት የተባለ አንድ ዘመናዊ የመክተፍ ሥልትን ይጠቀማል። መሕለፈቃሉን በቢክሪፕት በመክተፍ፣ አንድ አጥቂ አንድ የውሂበጎታ ቅጂን ማግኘት ቢችልም እንኳ፣ ወደ ጣቢያው ለመግባት እንደማይችል ግን እናረጋግጣለን። ማሳያ አፕልኬሽኑ ውስጥ ቢክሪፕትን ለመጠቀም፣ የቢክሪፕት (bcrypt) እንቁን በ‘እንቁፋይል (Gemfile
) ውስጥ ማከል ይኖርብናል (ዝርዝር 6.37))።
bcrypt
) እንቁን በ‘እንቁፋይል (Gemfile
) ውስጥ ማከል።
source 'https://rubygems.org'
gem 'rails', '6.1.4.1'
gem 'bcrypt', '3.1.13'
gem 'bootstrap-sass', '3.4.1'
.
.
.
ከዚያ እንደተለመደው ጠቅል-ጫን‘ን (bundle install
) አስኪዱ:-
$ bundle _2.2.17_ install
አሁን የተጠቃሚ ቅርጸቱን በተፈለገው የ‘መሕለፈቃል_ፈጪ (password_digest
) ባሕሪ እና በተፈለገው የቢክሪፕት እንቁ ስለተጫነ፣ በዝርዝር 6.38 ላይ እንደሚታየው፣ ለተጠቃሚ ቅርጸቱ ጥብቅ_መሕለፈቃል_አለው‘ን (has_secure_password
) ለማከል ዝግጁ ነን፡፡
has_secure_password
) ማከል። ቀይ 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
end
በዝርዝር 6.38 ውስጥ በ ቀይ አመልካች እንደተመለከተው፣ እና በማዘዥያ መስመሩ ላይ ማረጋገጥ እንደምትችሉት አሁን ፈተናወቹ ወድቀዋል:-
$ rails test
ይህ የሆነበት ምክንያት፣ በክፍል 6.3.1 ውስጥ እንደተገለጸው ጥብቅ_መሕለፈቃል_አለው (has_secure_password
) በ‘መሕለፈቃል (password
) እና በመሕለፈቃል ማረጋገጫ (password_confirmation
) ምናባዊ ባሕሪወች ላይ ማስረገጫዎችን ስለሚያስገድድ ሲሆን፤ በአንጻሩ ግን ዝርዝር 6.26 ውስጥ ያሉ ፈተናወች አንድ የ‘@ተጠቃሚ (@teteqami
) ተለዋዋጪን ያለ እነዚህ ባሕሪወች ስለሚፈጥሩ ነው፡-
def setup
@teteqami = Teteqami.new(sim: "Abnetawi Teteqami", emelekt: "teteqami@misalei.com")
end
ስለሆነም የፈተና ስብስቡ በድጋሚ እንዲያልፍ ለማድረግ፣ በዝርዝር 6.40 ውስጥ እንደሚታየው፣ አንድ የመሕለፈቃልን እና የሱን ማረጋገጫ ማከል ይኖርብናል።
test/models/teteqami_test.rb
require 'test_helper'
class TeteqamiTest < ActiveSupport::TestCase
def setup
@teteqami = Teteqami.new(sim: "Abnetawi Teteqami", emelekt: "teteqami@misalei.com",
password: "yonatan", password_confirmation: "yonatan")
end
.
.
.
end
በሩቢ ተርታ አገባብ መሰረት የ‘አዘጋጅ (setup
) ዘዴው ውስጥ ያለው የመጀመሪያው መስመር መጨረሻው ላይ አንድ ተጨማሪ ነጠላ ሰረዝ እንደሚያስፈልገው ልትገነዘቡ ይገባል (ክፍል 4.3.3)፡፡ ይህን ነጠላ ሰረዝ መተው፣ አንድ የአገባብ ስህተት እንዲፈጠር ያደርጋል፣ እንደዚህ አይነት ነገሮች በሚሲከሰቱ ጊዜ ስህተቶቹን ለመለየት እና ለመፍታት የራሳችሁን ቴክኒካዊ ስልት (ሳጥን 1.2) መጠቀም ይኖርባችኋል።
በዚህ ጊዜ ፈተናወቹ አረንጓዴመሆን አለባቸው፡-
$ rails test
ጥብቅ_መሕለፈቃል_አለው‘ን (has_secure_password
) በተጠቃሚ ቅርጸቱ (ክፍል 6.3.4) ውስጥ የማከል ጥቅሞችን በአጪር ጊዜ ውስጥ እናያለን፣ በመጀመሪያ ግን በመሕለፈቃል ጥበቃ ላይ አንድ አነስተኛ መስፈርትን እንጨምራለን።
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
በአጠቃላይ መሕለፈቃሎች ለመገመት አስቸጋሪ እንዲሆኑ፣ የመሕለፈቃል ሆሄወች ላይ፣ የአነስተኛ እርዝመት መስፈርትን ማድረጉ ጥሩ ልምድ ነው፡፡ በሬይልስ ውስጥ የመሕለፈቃል ማጠንከሪያን ለማስገደድ ብዙ አማራጮች አሉ፤ ነገር ግን ስራው እንዲቀልልን ቢያንስ አንድ አነስተኛ እርዝመትን እና አንድ የመሕለፈቃል ባሕሪው ባዶ መሆን እንደማይገባው የሚያስገድድ ማለት ሁለት መስፈርቶችን እናደርጋለን፡፡ ስድስትን (6) ልክ እንደ አንድ ምክንያታዊ አነስተኛ እርዝመት አድርጎ መምረጡ፣ በዝርዝር 6.42 ላይ የሚታየውን የማስረገጫ ፈተና ይሰጣል፡፡
test/models/teteqami_test.rb
require 'test_helper'
class UserTest < ActiveSupport::TestCase
def setup
@teteqami = Teteqami.new(sim: "Abnetawi Teteqami", emelekt: "teteqami@misalei.com",
password: "yonatan", password_confirmation: "yonatan")
end
.
.
.
test "መሕለፈቃል መኖር አለበት (ባዶ ያልሆነ)" do
@teteqami.password = @teteqami.password_confirmation = " " * 6
assert_not @teteqami.valid?
end
test "መሕለፈቃል አነስተኛ እርዝመት ሊኖረው ይገባል" do
@teteqami.password = @teteqami.password_confirmation = "ኤ" * 5
assert_not @teteqami.valid?
end
end
ዝርዝር 6.42 ላይ የተጠቀጠቀ በርካታ ምደባን መጠቀማችንን ልብ በሉ:-
@teteqami.password = @teteqami.password_confirmation = "ኤ" * 5
ይህ ለመሕለፈቃሉ እና ለማረጋገጫው አንድ የተወሰነ ዋጋን ለመመደብ ያዘጋጃል (በዚህ ጊዜ፣ አንድ እርዝመቱ 5 የሆነ ሃረግን ይገነባል፣ ሃረጉም ልክ በዝርዝር 6.14 ላይ እንደተደረገው፣ ሃረግ ማባዛትን በመጠቀም የተገነባ ነው።)
ተዛማጁን የተጠቃሚ ስም ከፍተኛ (maximum
) እርዝመት ማስገደጃውን በማየት፣ ለአንድ አነስተኛ (minimum
) እርዝመት ገደብ የሚጥለውን ኮድ፣ ለመገመት ትችሉ ይሆናል (ዝርዝር 6.16):-
validates :password, length: { minimum: 6 }
ይህንን የባዶ ያልሆኑ መሕለፈቃሎች ማስረገጫ፣ ከአንድ የ‘ኖረ ( presence
) ማስረገጫ (ክፍል 6.2.2) ጋር ማጣመሩ በዝርዝር 6.43 ውስጥ ወደሚታየው፣ የተጠቃሚ ቅርጸት ግኝት ይመራናል። (የ‘ጥብቅ_መሕልፈቃል_አለው (has_secure_password
) ዘዴ የ‘ኖረ (presence
) ማስረገጫን ያካትታል፣ የሚያሳዝነው ግን ማረጋገጫው የሚያረጋግጠው ባዶ የሆኑ የመሕለፈቃል መዝገቦችን ብቻ ነው። ማለትም ተጠቃሚዎች እንደ ' '
(ስድስት ክፍትቦታ) ያሉ መሕለፈቃሎችን እንዲፈጥሩ ያስችላቸዋል)
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 }
end
በዚህ ጊዜ ፈተናው አረንጓዴመሆን አለበት፡-
$ rails test:models
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
አሁን መሰረታዊው የተጠቃሚ ቅርጸት ተጠናቋል፣ በክፍል 7.1 ውስጥ አንድ የተጠቃሚ መረጃ ማሳያ ገጽን ለመስራት እንደ አንድ ቅድመ ዝግጅት ይሆነን ዘንድ፣ በውሂበጎታ ውስጥ አንድ ተጠቃሚን እንፈጥራለን፡፡ እንዲሁም የ‘አረጋግጥ (authenticate
) ዘዴ አስፈላጊነትን በአንክሮ ማየትን ጨምሮ፣ ጥብቅ_መሕለፈቃል_አለው‘ን (has_secure_password
) በተጠቃሚ ቅርጸቱ ላይ ማከሉ ያመጣውን ተጨባጪ ለውጥንም እንመረምራለን፡፡
ተጠቃሚዎች በድር በኩል ለማሳያ አፕልኬሽኑ ገና መመዝገብ (ይህ የምዕራፍ 7 ግብ ነው) ባይችሉም፣ አንድ አዲስ ተጠቃሚን ለመፍጠር ግን የሬይልስ ሰሌዳን እንጠቀማለን። ለአመቺነት በክፍል 6.1.3 ውስጥ የተወያየንበትን የ‘ፍጠር (create
) ዘዴን እንጠቀማለን፣ ነገር ግን በዚህ ጊዜ የተፈጠረው ተጠቃሚ ውሂበጎታው ላይ እንዲቀመጥ ለማድረግ በአንድ አሸዋሳጥን ውስጥ ላለመጀመር ጥንቃቄ እናደርጋለን፡፡ ይህ ማለት የሬይልስ ሰሌዳ (rails console
) ክፍለ ጊዜን መጀመር እና ከዚያ ከአንድ ብቁ ስም እና የኤመልእክት አድራሻ ጋር አንድ ብቁ የመሕለፈቃል እና ተዛማጅ የመሕለፈቃል ማረጋገጫን ያሟላ አንድ ተጠቃሚን መፍጠር ማለት ነው፡-
$ rails console
>> Teteqami.create(sim: "Michael Hartl", emelekt: "michael@misalei.com",
?> password: "yonatan", password_confirmation: "yonatan")
=> #<Teteqami id: 1, sim: "Michael Hartl", emelekt: "michael@misalei.com",
"2020-11-12 00:00:18", updated_at: "2020-11-12 00:00:18",
password_digest: [FILTERED]>
ይህ መስራቱን ለማረጋገጥ፣ እስኪ በምስል 6.1021 ላይ እንደሚታየው፣ የውጎ አሳሽ ለቀመቋ (“DB Browser for SQLite”) ፕሮግራምን በመጠቀም፣ በብልጸጋ ውሂበጎታ ውስጥ የ‘ተጠቃሚዎች (teteqamis
) ሰንጠረዥ ግኝትን እንመልከት፡፡ (የደመና ቅ.ማ.አን እየተጠቀማችሁ ከኖነ፣ ልክ በምስል 6.5 ላይ እንደሚታየው አድርጋችሁ የውሂበጎታ ፋይሉን ማውረድ ይኖርባችኋል፡፡) አምዶቹ በምስል 6.9 ውስጥ ከተበየኑት የውሂብ ቅርጸት ባሕሪወች ጋር እንደሚዛመዱ አስተውሉ፡፡
ወደ ሰሌዳው በመመለስ ዝርዝር 6.43 ውስጥ ያለው የ‘ጥብቅ_መሕለፈቃል_አለው (has_secure_password
) ዘዴ ያስገኘውን ውጤት የ‘መሕለፈቃል_ፈጪ (password_digest
) ባሕሪ ላይ መመልከት እንችላለን፡-
>> ተጠቃሚ = Teteqami.find_by(emelekt: "michael@misalei.com")
>> ተጠቃሚ.password_digest
=> "$2a$12$WgjER5ovLFjC2hmCItmbTe6nAXzT3bO66GiAQ83Ev03eVp32zyNYG"
ይህ የተጠቃሚውን ቁስ ለማስጀመር ያገለገለ የተከተፈው የ‘ዮናታን ("yonatan"
) መሕለፈቃል ስሪት ነው። ቢሲክሪፕትን በመጠቀም የተገነባ ስለሆነ፣ የመጀመሪያውን መሕለፈቃል22 ለማግኘት ፍጪውን ተጠቅሞ ማስላቱ (ኮምፒተሮችን ተጠቅሞ ማስላቱ) ፈጽሞ የማይታሰብ ነው።
በክፍል 6.3.1 ላይ እንደተመለከተው፣ ጥብቅ_መሕለፈቃል_አለው (has_secure_password
) በተዛማጁ ቅርጸት ቁሶች ላይ አንድ የ‘አረጋግጥ (authenticate
) ዘዴን በራስሰር ያክላል፡፡ ይሄ ዘዴ ለአንድ የተለየ ተጠቃሚ የተሰጠ አንድ መሕለፈቃልን፣ ፍጪውን በማስላት እና ውጤቱን በውሂበጎታው ውስጥ ካለው መሕለፈቃል_ፈጪ (password_digest
) ጋር በማነጻጸር ብቃቱን ይወስናል። ቀደም ብለን ለፈጠርነው ተጠቃሚ አንዳንድ ብቃት የለላቸው መሕለፈቃሎችን እንደሚከተለው አድርገን በመሞከር ይህንን እወንውታ ማረጋገጥ እንችላለን፡-
>> ተጠቃሚ.authenticate("ትክክለኛ_ያልሆነ_መሕለፈቃል")
false
>> ተጠቃሚ.authenticate("አታላይ")
false
እዚህ ጋር የ‘ተጠቃሚ.አረጋግጥ (ተጠቃሚ.authenticate
) ዘዴው ብቃት ለሌለው መሕለፈቃል ሃሰት‘ን (false
) ይመልሳል፡፡ በብቁ መሕለፈቃል የምናረጋግጥ ከሆንን ግን የ‘አረጋግጥ (authenticate
) ዘዴው ተጠቃሚውን ራሱን ማለት ተጠቃሚ ቁሱን ይመልስልናል:-
>> ተጠቃሚ.authenticate("yonatan")
=> #<Teteqami id: 1, sim: "Michael Hartl", emelekt: "michael@misalei.com",
created_at: "2019-08-22 03:15:38", updated_at: "2019-08-22 03:15:38",
password_digest: [FILTERED]>
በምዕራፍ 8 ላይ የተመዘገቡ ተጠቃሚዎችን ወደ ጣቢያችን ለማስገባት የ‘አረጋግጥ (authenticate
) ዘዴን እንጠቀማለን፡፡ በእርግጥ የ‘አረጋግጥ (authenticate
) ዘዴው ተጠቃሚውን እንዲመልስ ማድረጉ ለእኛ አስፈላጊ አይሆንም፤ ለኛ የሚያስፈልገን በአንድ የቡልየን አውድ ውስጥ አንድ የ‘እውነት (true
) ዋጋን እንዲመልስልን ብቻ ነው፡፡ አናጋ አናጋ !!
አንድ ቁስን ወደ ተጓዳኙ የቡልየን ዋጋ ይለውጣል ተብለን በክፍል 4.2.2 ውስጥ እንደተማርን ታስታውሳላችሁ፣ እሱ ተጠቃሚ.አረጋግጥ (ተጠቃሚ.authenticate
) ላይ ተግባሩን በጥሩ ሁኔታ እንደሚተገብርም ማየት እንችላለን:-
>> !!ተጠቃሚ.authenticate("yonatan")
=> true
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
save
) ዘዴን ጥሩበት፣ ለምን ተጠቃሚው በውሂበጎታው ላይ መቀመጥ አልቻለም?
በዚህ ምዕራፍ ውስጥ፣ ከባዶ ጀምረን በስም በኤመልእክት እና በመሕለፈቃል ባሕሪወች ዋጋቸው ላይ በርካታ አስፈላጊ መስፈርቶችን የሚያስገድዱ ማስረገጫዎችን ያጣመረ አንድ የሚሰራ የተጠቃሚ ቅርጸትን ፈጥረናል፡፡ በተጨማሪም፣ አንድ በተሰጠ መሕለፈቃል ላይ፣ ተጠቃሚዎችን በጥብቅ ማረጋገጥ ችለናል፡፡ በአስራ ሁለት መስመር ኮዶች ብቻ ይህንን የመሰለ ችሎታ ማግኘቱ በጣም የሚያስደንቅ ነው፡፡
የእያንዳንዱን ተጠቃሚ መረጃ የሚያሳይ አንድ ገጽን ጨምሮ፣ በሚቀጥለው ምዕራፍ 7 ላይ አዲስ ተጠቃዎችን የሚፈጥር አንድ የመመዝገቢያ ቅጽን እንሰራለን፡፡ ከዚያ በምዕራፍ 8 ላይ ተጠቃሚዎች ወደ ጣቢያው መግባት እንዲችሉ ለማስቻል ክፍል 6.3 ላይ ያለውን የማረጋገጫ ፋብሪካ እንጠቀማለን፡፡
ጊትን እየተጠቀማችሁ ከሆነ እና እስከአሁን ድረስ ምንም ካላቀላቀላችሁ፣ አሁን ጊዜው ለማቀላቀል የተመረጠ ይሆናል፡-
$ rails test
$ git add -A
$ git commit -m "አንድ መሰረታዊ የተጠቃሚ ቅርጸትን መስራት (ጥብቅ መሕለፈቃሎችን ጨምሮ)"
ከዚያ ወደ ዋና ቅርንጫፉ መልሳችሁ አዋህዱ እና ወደ ሩቁ ማከማቻ ግፉት:-
$ git checkout main
$ git merge ተጠቃሚዎችን-መቅረጽ
$ git push
በምርት ላይ የተጠቃሚ ቅርጸቱ እንዲሰራ ለማድረግ፣ በሃረኩ ላይ መፍለሶችን ማስኬድ ይኖርብናል፣ ይህንንም በሃረኩ አስኪድ (heroku run
) ማድረግ እንችላለን፡-
$ rails test
$ git push heroku
$ heroku run rails db:migrate
ይህን በአንድ የምርት ሰሌዳ ውስጥ በማስኬድ፣ መስራቱን ማረጋገጥ እንችላለን፡-
$ heroku run rails console --sandbox
>> Teteqami.create(sim: "Michael Hartl", emelekt: "michael@misalei.com",
?> password: "yonatan", password_confirmation: "yonatan")
=> #<Teteqami id: 1, sim: "Michael Hartl", emelekt: "michael@misalei.com",
"2020-11-12 00:00:18", updated_at: "2020-11-12 00:00:18",
password_digest: [FILTERED]>
has_secure_password
) ዘዴን በመጠቀም አንድ ጥብቅ መሕለፈቃልን አንድ ቅርጸት ላይ ማከል እንደምንችል ተምረናል።
t
) ቁስ ይህንን እንዴት በትክክል እንደሚሰራው ለማወቅ መጨነቅ የለባችሁ። የእንቆቅልሽ ምንጣፍ (Abstraction Layer) አስደሳችነቱ ስለሱ ማወቅ የማያስፈልገን መሆኑ ነው። እኛ የሚያስፈልገን የ‘ሰ (t
) ቁስ ስራውን በሚገባ እንደሚሰራ መተማመን ብቻ ነው፡፡update_attributes
) በመባል ይታወቅ ነበረ።Teteqami.new
) የሚገኙ ውጤቶችን እና ወዘተረፈ እንደማለት ነው፡፡"Michael Hartl"@misalei.com
ከጥቅስ ምልክቶች ጋር በመሃል ክፍት ቦታ ያለው የኤመልእክት አድራሻ በደንቡ መሰረት ተቀባይነት ያለው መሆኑን ታውቃላችሁ? የሚገርም ነገር ነው፣ ነገር ግን ይሄ የተለመደ አይደለም።i
ግን ሁሉንም ዓይነት የእንግሊዝኛ ፊደላት መቀበልን/ማዛመድን ያስገድዳል፡፡db/test.sqlite3
) ውስጥ አለ፡፡teteqamis
) ሰንጠረዥ ላይ፣ ይህንን የኤመልእክት አድራሻ መረጃ-ጠቋሚ መጨመር እንችል ነበር፣ ነገር ግን ውሂበጎታውን ወደኋላ መመለስ እና ከዚያ በኋላ ደግሞ እንደገና ማፍለስን ይጠይቃል፡፡ የኛ አሰራር ግን የሬይልስ የአሰራር ሂደትን በመከተል፣ ™ የውሂብ ቅዳችንን መቀየር በፈለግን ጊዜ ፍልሰትን መጠቀም ይሆናል፡፡has_secure_password
) የኮድ ምንጩ ሳይቀር የዚህ ስህተት ተካፋዮች ሁነዋል፡፡ የዚህ ቃል ስነአባባል (Terminology) የተሳሳተ ነው፣ ምክንያቱም የመመስጠር አሰራር የተነደፈው፣ አንድ ነገርን ወደነበረበት መልሶ እንዲያቀርብ ነው፡፡ ይህ ማለትም፣ አንድ ነገርን የመመስጠር ችሎታ ካለ፣ ሚስጥረቢስ (Decrypt) የማድረግ ማለት የተመሰጠረውን ወደ ነበረበት የመቀልበስ ችሎታ አለ ማለት ነው፡፡ በተቃራኒው፣ አንድ መሕለፈቃል እንዲከተፍ የማስላቱ ዋናው ምክንያት፣ ፍጹም ወደነበረበት የማይመለስ እንዲሆን ነው፤ ስለሆነም ዋናውን የመሕለፈቃል ከፍጪው ለማግኘት ማስላቱ ፍጹም አስቸጋሪ ነው። በሌላ አማርኛ ፍጪውን አስልቶ ኦርጅናሉን መሕለፈቃል ለማገኘት ከመጣር ይልቅ ግመልን በመርፌ ቀዳዳ ማሳለፉ ይቀላል። ለዚህም ነው አባባሉ ትክክል ያልሆነው። (ለክቡር አንባቢ አቶ አንዲ ፊሊፕስ ይህንን የተሳሳተ አባባል እንዳስተካክል ስላበረከቱልኝ አስተያየት በጣም አመሰግናለሁ።)21. በሆነ ምክንያት የሆነ ችግር ከተከሰተ፣ ውሂበጎታውን እንደሚከተለው አድርጋችሁ እንደ አዲስ ማስጀመር ትችላላችሁ:-
$ rm -f development.sqlite3
) ትእዛዝን በማዘዥያ መስመሩ ላይ ማስኬድ፣ (በነገራችን ላይ ይህንን ለማድረግ ከዚህ የበለጠ ዘዴ ምዕራፍ 7 ላይ እንማራለን፡፡)
$ rails db:migrate
) ዘዴን በመጠቀም፣ እንደ አዲስ ፍልሰቱን ማስኬድ