በዚህ ምዕራፍ ውስጥ ተጠቃሚዎች ሌሎች ተጠቃሚዎችን መከተል እና አለመከተል የሚያስችል አንድ ማህበራዊ ንጣፍን በማከል የሬይልስ ስልጠና ማሳያ አፕልኬሽኑን እናጠናቅቀዋለን፣ ይህም በእያንዳንዱ ተጠቃሚ የመነሻ ገጽ ላይ፣ አንድ የክትል ተጠቃሚዎች የአጪርጽሑፎች ሁኔታ ቀላቢን ያሳያል፡፡ በክፍል 14.1 ላይ በተጠቃሚዎች መካከል፣ ትስስርን እንዴት መቀረጽ እንደምንችል በመማር እንጀምር እና በክፍል 14.2 ላይ (እግረ መንገዳችንን ኤጃክስ (Ajax) ከተባለ ፕሮግራም ጋር መተዋወቅን ጨምሮ) ከዚሁ ጋር የሚዛመደውን የድር በይነገጽ እንገነባለን፡፡ ክፍል 14.3 ላይ አንድ የተሟላ አገልግሎት የሚሰጥ የሁኔታ ቀላቢ ግንባታን እንጨርሳለን፡፡
ይህ የመጨረሻ ምዕራፍ፣ ሁኔታ ቀላቢውን ለመስራት የተወሰኑ የሩቢ እና የተ.መ.ቋ ሽወዳን አካቶ፣ በዚህ ስልጠና ውስጥ በጣም ፈታኝ የሆኑ አንዳንድ ነገሮችን ያካትታል። በእነዚህ ምሳሌዎች አማካኝነትም፣ ሬይልስ የረቀቁ የውሂብ ቅርጸቶችን ሳይቀር እንኳ እንዴት አድርጎ ሊተገብር እንደሚችል ትመለከታላችሁ፤ ይህም ለወደፊት የተወሰኑ መስፈርቶች ያላቸው አፕልኬሽንኖችን ለመገንባት በምትፈልጉበት ጊዜ፣ በጥሩ ሁኔታ ሊያገለግላችሁ ይችላል። ከሰልጣኝ፣ ራሱን ወደ ቻለ አበልጻጊ ለመሽጋገር ያግዛችሁ ዘንድ፣ ክፍል 14.4 የተወሰኑ የላቁ የመረጃ ምንጮችን የሚጠቁም ምክርን ያቀርባል፡፡
በዚህ ምዕራፍ ውስጥ ያለው ነገር በጣም ፈታኝ ስለሆነ፣ አንድም ኮድ ከመጻፋችን በፊት ለአንዳፍታ ረጋ ብለን በይነገጹን እንቃኛለን፡፡ በቀደሙት ምዕራፎች እንደተጠቀምነው ሁሉ፣ አሁንም ገና በጅማሬው አንዳንድ ስእላዊ መግለጫወችን በመጠቀም፣ መጨረሻ ላይ እውን የምናደርጋቸውን የገጾች አምሳል እናያለን፡፡1 ሙሉ የገጹ ፍሰት እንደሚከተለው ይሄዳል:- አንድ ተጠቃሚ (ሳሙኤል ለኣከ) ከራሱ የመገለጫ ገጽ ይጀምራል (ምስል 14.1)፣ ቀጥሎም የሚከተለውን አንድ ተጠቃሚ ለመምረጥ ወደ ተጠቃሚዎች ገጽ ይሄዳል (ምስል 14.2)። ከዚያ በመቀጠል ሳሙኤል ወደ ሌላ ተጠቃሚ ማለት ወደ በላይነሽ ኪዳነ መገለጫ ገጽ ይሄድ እና (ምስል 14.3) እሷን ለመከተል የ “ተከተል” አዝራርን ጠቅ ያደርጋል፡፡ ይህ ሂደት የ “ተከተል” አዝራርን ወደ “አትከተል” አዝራር ይለውጠዋል፤ እንዲሁም የበላይነሽን የ“ተከታዮች” ቁጥርን በአንድ እንዲጨምር ያደርገዋል (ምስል 14.4)። ሳሙኤል ወደ ራሱ መነሻ ገጽ ሲዘዋወር፣ የ “ሚከተላቸው/ሏት” ቁጥር እንደጨመረ እና የበላይነሽን አጪርጽሑፎች በራሱ ሁኔታ ቀላቢ ላይ እንዳገኘ ይመለከታል (ምስል 14.5)፡፡ የተቀረው የዚህ ምዕራፍ ስራ፣ የዚህን ገጽ ፍሰት በትክክል እንዲሰራ ለማድረግ የተመደበ ይሆናል፡፡
ተጠቃሚዎች መከተልን ተግባራዊ ለማድረግ፣ የመጀመሪያው ሂደታችን አንድ የውሂብ ቅርጸትን መገንባት ነው፣ ይህንን መገንባቱ እንደሚታሰበው ቀላል አይደለም፡፡ እንዲሁ በገርነት ስናየው፣ አንድ የ‘ብዙ_አለው (has_many
) ትስስርን በመጠቀም የሚሰራ ይመስላል፤ ማለት አንድ ተጠቃሚ ብዙ ተከታዮች አሉት (has_many
) ብዙ ተጠቃሚዎችንም ይከተላል (has_many
) ብለን በገርነት ልንጠቀምበት እናስብ ይሆናል፡፡ በኋላ ላይ እንደምንመለከተው፣ በዚህ አቀራረብ ላይ አንድ የተወሰነ ችግር እንዳለ እና በ‘ብዙ_አለው በኩል (has_many :through
) የተባለውን የመተሳሰር ዘዴን በመጠቀም ይህንን ችግር እንዴት ማስተካከል እንደሚቻል እንማራለን፡፡
የጊት ተጠቃሚዎች፣ እንደተለመደው አንድ አዲስ የርዕስ ቅርንጫፍን መፍጠር ይኖርባችኋል:-
$ git checkout -b ተጠቃሚዎችን-መከተል
ተጠቃሚዎችን ለመከተል፣ አንድ የውሂብ ቅርጽን ለመስራት፣ እንደ አንድ የመጀመሪያ እርምጃ ይቆጠር ዘንድ፣ እስኪ አንድ የተለመደ ሁኔታን እንመልከት፡፡ እንበል አንድ ተጠቃሚ ሌላ ተጠቃሚን እንደሚከተል አድርጋችሁ በህሊናችሁ አስቡ፤ እንበል ለምሳሌ፣ ሳሙኤል በላይነሽን እየተከተላት ነው፣ በላይነሽ የሳሙኤል ክትል ናት፤ ስለዚህ ሳሙኤል ተከታይ (teketay)፡ በላይነሽ ደግሞ ክትል (ktl) ትሆናለች ማለት ነው፡፡ የሬይልስ የብዙነት ነባሪ አሰራርን ስንጠቀም፣ አንድ የተሰጠ ተጠቃሚን የሚከተሉት፣ የሁሉም ተጠቃሚዎች ስብስብ፣ የተጠቃሚው ተከታዮች (teketayoch) ናቸው ማለት ነው፤ ስለዚህ በላይነሽ.ተጠቃሚዎች (belaynesh.teketayoch
) እነዚህን ተጠቃሚዎች የያዘ አንድ ድርድር ነው ማለት ነው፡፡ እንደ አጋጣሚ ሆኖ የተገላቢጦሹ ትክክል አይደለም፤ የሁሉም የክትል ተጠቃዎች ስብስብ ደግሞ በነባሪነት ክትሎች (ktls) መባል ነበረበት፣ ሆኖም ይህ ቃል ከሰዋሰው ስርዓት ውጪ የሆነ ጉዳይ ነው፡፡ ስለዚህ የትዊተርን አሰራር በመከተል፣ እነዚህን ሚከተላቸው (miketelachew) ብለን እንጠራቸዋለን (ልክ “50 ሚከተላቸው/ሏት፣ 75 ተከታዮች” እንደሚለው ማለት ነው)፣ ስለሆነም የተጠቃሚው ተዛማጅ ድርድር ሳሙኤል.ሚከተላቸው (samuel.miketelachew
) ይሆናል ማለት ነው፡፡
ይህ ውይይት የተከታይ ተጠቃሚዎች ውሂብን ለመቅረጽ፣ በምስል 14.6 ላይ እንደሚታየው፣ አንድ ሚከተላቸው (miketelachew
) የተባለ ሰንጠረዥን ከአንድ ብዙ_አለው (has_many
) ማሕበር ጋር መጠቀም እንዳለብን ይጠቁማል። ተጠቃሚ.ሚከተላቸው (teteqami.miketelachew
) (የሚለው ኮድ) አንድ የተጠቃሚዎች ክምችት መሆን ስላለበት፣ በክትል_መታወቂያ (ktl_id
) እና በ‘ተከታይ_መታወቂያ (teketay_id
) የሚታወቁት አምዶች አንድ ማሕበርን እንዲመሰርቱ፣ እያንዳንዱ የ‘ሚከተላቸው (miketelachew
) ሰንጠረዥ ረድፍ አንድ ተጠቃሚ መሆን ይኖርበታል።2 ከዚህ በተጨማሪም፣ እያንዳንዱ ረድፍ የሚያመለክተው አንድ ተጠቃሚን ስለሆነ፣ የተጠቃሚውን ስም፣ የኤመልእክት አድራሻውን፣ መሕለፈቃሉን እና ወዘተረፈ ያሉ ባሕሪዎችን በሙሉ ማካተት ይኖርብናል ማለት ነው።
በምስል 14.6 ላይ የተመለከትነው የውሂብ ቅርጸት ትልቁ ችግር ድግግሞሹ መብዛቱ ነው፤ እያንዳንዱ ረድፍ የሚይዘው የተጠቃሚውን መታወቂያ ብቻ ሳይሆን በ‘ተጠቃሚዎች (teteqamis
) ሰንጠረዥ ውስጥ ከድሮውም የተካተቱትን ሁሉንም መረጃዎች ነው። ከዚህ የከፋው ደግሞ፣ የተጠቃሚውን ተከታዮች ቅድን ለመቅረጽ አንድ ሌላ ድግግሞሽ የበዛበት የ‘ተከታዮች (teketayoch
) ሰንጠረዥ ማዘጋጀት ማስፈለጉ ነው፡፡ ይህ የውሂብ ቅርጸት መረጃዎችን የማሻሻል ስራን እጅግ ከባድ ያደርጋል፤ ለምሳሌ፣ አንድ ተጠቃሚ ስሙን በቀየረ ቁጥር፣ በ‘ተጠቃሚዎች (teteqamis
) ሰንጠረዥ ላይ ያለውን የተጠቃሚውን ስም፣ ብቻ ሳይሆን በ‘ሚከተላቸው (miketelachew
) እና በ‘ተከታዮች (teketayoch
) ሰንጠረዥ ውስጥ እያንዳንዱ ረድፍ ላይ የሚገኘውን ስም ሳይቀር ማዘመን ይኖርብናል ማለት ነው፡፡
እዚህ ላይ ያለው ችግር አንድ መሰረታዊ እንቆቅልሽን አለመፍታታችን ያሳያል፡፡ ትክክለኛውን ቅርጸት ለመቀረጽ አንዱ መንገድ፣ በአንድ ድር አፕልኬሽን ውስጥ የ‘ሚከተላቸው (miketelachew) ተግባርን እንዴት አድርገን እንደምንተገብር መገንዘብ ነው፡፡ በክፍል 7.1.2 ላይ እንደተመለከትነው፣ የው.ሁ.ማ መዋቅር የሚፈጠሩ እና የሚደመሰሱ ሃብቶችን እንደሚያሳትፍ አስታውሱ፡፡ ይህ ደግሞ ሁለት ጥያቄዎችን እንድንጠይቅ ያነሳሳናል፤ አንደኛው ጥያቄ፣ አንድ ተጠቃሚ ሌላኛውን እየተከተለ ከሆነ የሚፈጠረው ነግር ምንድን ነው? ሲሆን ሁለተኛው ጥያቄ ደግሞ፣ አንዱ ተጠቃሚ አንዱን ተከትሎት ቆይቶ እንደገና ባይከተለው የሚጠፋው ነገርስ ምንድን ነው? ማለት በዚህ ጊዜ የተደመሰሰው ነገር ምንድን ነው? የሚሉት ናቸው፣ እነዚህን ነገሮች በማነጻጸር ረገድ ስንመለከት፣ በእነዚህ ክስተቶች ምክንያት፣ አፕልኬሽኑ በሁለት ተጠቃሚዎች መካከል አንድ ትስስርን መፍጠር ወይም መሰረዝ እንደሚኖርበት እንገነዘባለን፡፡ ከዚያ በኋላ አንድ ተጠቃሚ ብዙ ትስስሮች ስለሚኖሩት፣ በእነዚህ ትስስሮች በኩል ብዙ ሚከተላቸው (miketelachew
) (ወይም ተከታዮች (teketayoch
)) እንደሚኖሩትም በሚገባ እንገነዘባለን፡፡
የአፕልኬሽናችንን የውሂብ ቅርጸትን በተመለከተ፣ አንድ ልናስተናግደው የሚገባ ተጨማሪ ነገር አለ፤ የፌስቡክ-አይነት ጓደኝነት ተመጣጣኝ ነው፣ ይህ ማለት አንድ ሰው ከሌላ ሰው ጋር ጓደኛ የሚሆነው ሁለቱም ከተስማሙ ብቻ ነው፣ ማለት ነው፤ ይህም ከትዊተር-አይነት ጓደኝነት ጋር ተቃራኒ ነው (ቢያንስ የውሂብ ቅዱን በተመለከተ)፣ የትዊተር የመከተል ትስስር ተመጣጣኝ አይደለም ሳሙኤል በላይነሽን ሳይከተላት በላይነሽ ሳሙኤልን ልትከተለው ትችላለች። በእነዚህ ሁለት ሁኔታወች መካከል ያለውን ልዩነት ለመለየት፣ ንቅ (nq) እና ያልተካፈለ (yaltekafele) ትስስሮች በማለት የራሳችን የሆኑ ስነአባባሎችን እንፈጥራለን። ሳሙኤል በላይነሽን ከተከተላት እና በላይነሽ ሳሙኤልን ካልተከተለችው፣ ሳሙኤል ከበላይነሽ ጋር አንድ ንቅ ትስስር ሲኖረው በላይነሽ ደግሞ ከሳሙኤል ጋር አንድ ያልተካፈለ ትስስር አላት ማለት ነው፡፡3
አሁን አንድ ሚከተላቸው (miketelachew) ተጠቃሚዎች ዝርዝርን ለማመንጨት፣ ንቁ ትስስሮችን በመጠቀም ላይ እናተኩራለን፤ በክፍል 14.1.5 ውስጥ ደግሞ ያልተካፈሉ (yaltekafele) ትስስሮችን እንመለከታለን፡፡ ምስል 14.6 እንዴት ተደርጎ መተግበር እንደሚገባው እንዲህ ሲል ይጠቁማል፤ እያንዳንዱ የሚከተል ተጠቃሚ በተለየ የ‘ክትል_መታወቂያ (ktl_id
) ተለይቶ ስለሚታወቅ፣ ሚከተላቸው‘ን (miketelachew
) ወደ አንድ ንቅ_ትስስሮች (nq_tssrs
) ሰንጠረዥ መለወጥ እንደምንችል፤ የሚከተለውን ተጠቃሚ ከተጠቃሚዎች (teteqamis
) ሰንጠረዥ ፈልገን ለማውጣት ክትል_መታወቂያ‘ውን (ktl_id
) ስለምንጠቀም፣ የተጠቃሚውን ዝርዝር መረጃወች በ‘ንቅ_ትስስሮች (nq_tssrs
) ሰንጠረዥ ውስጥ ከማስገባት እንደምንቆጠብ ይጠቁማል። የውሂብ ቅርጸት አቀራረጹ በምስል 14.7 ላይ ይታያል፡፡
ከአንድ ተዛማጅ ትስስር (Tssr) ቅርጸት ጋር፣ ለሁለቱም ማለት ለንቅ እና ለያልተካፈለ ትስስሮች አንድ የውሂበጎታ ሰንጠረዥን መጠቀማችን ስለማይቀር፣ ለሰንጠረዡ ስም ትስስር (tssr) የተባለ አጠቃላይ ስነቃልን እንጠቀማለን። ስለሆነም የትስስሩ የውሂብ ቅድ፣ በምስል 14.8 ላይ እንደሚታየው ይሆናል፡፡ ሁለቱንም ማለት የንቅ ትስስርን እና የያልተካፈለ ትስስር ቅርጸቶችን ለማስመሰል፣ የትስስር ቅርጸትን እንዴት መጠቀም እንደሚቻል በክፍል 14.1.4 ላይ ማየት እንጀምራለን፡፡
ትግበራውን ለመጀመር፣ በቅድሚያ ከምስል 14.8 ጋር የሚዛመድ አንድ ፍልሰትን እናመነጫለን:-
$ rails generate model Tssr teketay_id:integer ktl_id:integer
ትስስሮችን በ‘ተከታይ_መታወቂያ (teketay_id
) እና በ‘ክትል_መታወቂያ‘ው (ktl_id
) መሰረት ስለምንፈልግ፣ ለቅልጥፍና በዝርዝር 14.1 ውስጥ እንደታየው፣ በእያንዳንዱ አምድ ላይ አንድ የመረጃ-ጠቋሚን ማከል ይኖርብናል፡፡
db/migrate/[ማህተመጊዜ]_create_tssrs.rb
class CreateTssrs < ActiveRecord::Migration[6.1]
def change
create_table :tssrs do |t|
t.integer :teketay_id
t.integer :ktl_id
t.timestamps
end
add_index :tssrs, :teketay_id
add_index :tssrs, :ktl_id
add_index :tssrs, [:teketay_id, :ktl_id], unique: true
end
end
ዝርዝር 14.1 አንድ ተጠቃሚ ሌላ ተጠቃሚን ከአንድ ጊዜ በላይ መከተል እንዳይችል (በ‘ተከታይ_መታወቂያ (teketay_id
) እና በ‘ክትል_መታወቂያ (ktl_id
)) ጥንድ ላይ ልዩነትን የሚያስፈጽም አንድ ባለብዙ ቁልፍ የመረጃ-ጠቋሚዎችንም ያካትታል፡፡ (ይህንን ከዝርዝር 6.29 የኤመልእክት ልዩ የመረጃ-ጠቋሚ እና ዝርዝር 13.3 ላይ ካለው፣ ባለብዙ የመረጃ-ጠቋሚዎች ጋር አነጻጽሩ፡፡) ስለሆነም ከክፍል 14.1.4 ጀምረን እንደምናየው፣ የእኛ የተጠቃሚ በይነገጽ ይህ ነገር እንዲከሰት አይፈቅድም፣ ነገር ግን አንድ ተጠቃሚ ለማንኛውም የተደጋገሙ ትስስሮችን (ለምሳሌ፣ እንደ ከርል (curl
) ያለ የማዘዥያ መስመርን ተጠቅሞ) ለመፍጠር ቢሞክር፣ አንድ ልዩ የመረጃ-ጠቋሚን ከወዲሁ ማከላችን አንድ ስህተት እንዲነሳ ያዘጋጅልናል፡፡
የ‘ትስስሮች (tssrs
) ሰንጠረዡን ለመፍጠር፣ እንደተለመደው ውሂበጎታውን እናፈልሳለን:-
$ rails db:migrate
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
1
ለሆነው ተጠቃሚ የዚህ:- teteqami.miketelachew.map(&:id)
ዋጋ ምን ይሆናል? (የዚህን:- map(&:የዘዴ_ስም)
አይነት ጥለትን በክፍል 4.3.2 ላይ እንደተመለከትን አስታውሱ፡፡ ይሄ የ teteqami.miketelachew.map(&:id)
ዘዴ፣ አንድ መታወቂያዎችን (ids) የያዘ ድርድርን ይመልሳል።)
2
ለሆነው ተጠቃሚ፣ የሚከተለውን መታወቂያዎች ለማግኘት ይህንን:- teteqami.miketelachew
ተጠቀሙ። የተጠቃሚው የዚህ teteqami.miketelachew.map(&:id)
ዋጋስ ምንድነው?
ተጠቃሚ የሚከተላቸውን እና ተከታዮችን ከመተግበራችን በፊት፣ በቅድሚያ በተጠቃሚዎች እና በትስስሮች መካከል ያለውን ማሕበር መመስረት ይኖርብናል፡፡ አንድ ተጠቃሚ ብዙ (has_many
) ትስስር ይኖሩታል፤ እናም (አንድ ትስስር ሁለት ተጠቃሚዎችን የሚያሳትፍ እንደመሆኑ መጠን) ትስስሩ የሁለቱም ማለት የአንድ የሚከተላቸው ተጠቃሚ እና የአንድ የተከታዮች ተጠቃሚ ነው (belongs_to
) ማለት ነው።
በክፍል 13.1.3 ውስጥ፣ አጪርጽሑፎች ላይ እንዳደረግነው ሁሉ፣ እዚህ ላይም የተጠቃሚውን ማሕበር በመጠቀም፣ አንድ አዲስ ትስስርን በዚህ ዓይነት ኮድ እንፈጥራለን:-
teteqami.nq_tssrs.build(ktl_id: ...)
በአሁኑ ጊዜ፣ የአፕልኬሽኑ ኮድ፣ በክፍል 13.1.3 ካለው ኮድ ጋር ተመሳሳይነት ይኖረዋል ብላችሁ ትጠብቁ ይሆናል፣ ተመሳሳይ አይደለም፣ እዚህ ላይ ሁለት ትልቅ ልዩነቶች አሉ፡፡
በመጀመሪያ፣ በተጠቃሚ/በአጪርጽሑፍ ማሕበር ሁኔታ ላይ ይህንን መጻፍ እንችል ነበር:-
class Teteqami < ApplicationRecord
has_many :achrtshufs
.
.
.
end
ይህ ይሰራ ነበር፣ ይህ የሆነበት ምክንያትም፣ ሬይልስ በተለምዶ ከአንድ አጪርጽሑፍ ቅርጸት ጋር የሚዛመድ አንድ የ‘:አጪርጽሑፎች (:achrtshufs
) ወካይን ሰለሚመለከት ነው፡፡4 በአሁኑ ሁኔታ ላይ ግን ይህንን ኮድ መጻፍ ይጠበቅብናል:-
has_many :nq_tssrs
ምንም እንኳ ቅርጸቱ ከስር መሰረቱ ትስስር ተብሎ የሚታውቅ ቢሆንም፣ ሬይልስ ቅርጸቱን ይፈልግ ዘንድ፣ የቅርጸቱን የክፍል ስም ለሬይልስ መንገር ይኖርብናል፡፡
በመቀጠል፣ ይህንን ኮድ በአጪርጽሑፍ ቅርጸቱ ውስጥ ከመጻፋችን በፊት:-
class Achrtshuf < ApplicationRecord
belongs_to :teteqami
.
.
.
end
ይሰራ ነበር፤ ይህ የሆነበት ምክንያትም የአጪርጽሑፎች (achrtshufs
) ሰንጠረዥ ተጠቃሚውን ለመለየት (ክፍል 13.1.1) አንድ የ‘ተጠቃሚ_መታወቂያ (teteqami_id
) ባሕሪ ስላላው ነው፡፡ በዚህ ሁኔታ ላይ ሁለት የውሂበጎታ ሰንጠረዦችን ለማገናኘት የሚጠቅመው መታወቂያ (id) የውጪ ቁልፍ በመባል ይታወቃል፤ እናም ለአንድ የተጠቃሚ ቅርጸት ቁስ፣ የውጪ ቁልፉ የ‘ተጠቃሚ_መታወቂያ‘ው (teteqami_id
) በሚሆንበት ጊዜ፣ ሬይልስ ባለው ሁኔታ ላይ በመመርኮዝ በራስሰር ማሕበሩን ያውቃል፣ ሬይልስ አንድ የውጪ ቁልፍን ለመስራት የዚህ <ክፍል>_መታወቂያ
ዓይነት ቅጽን በነባሪ ይጠብቃል፡፡ ይህ ማለት የክፍል ስሙ እንደዚህ <class>
በንዑስ ፊደል የተጻፈ መሆን ይገባዋል ማለት ነው፡፡5 በአሁኑ ሁኔታ ላይ፣ የተጠቃሚዎች ጉዳይ ላይ እየሰራን ቢሆንም፣ ሌላውን ተጠቃሚ የሚከተለው አንድ ተጠቃሚ፣ አሁን የሚለየው፣ ተከታይ-መታወቂያ (teketay_id
) በተባለው የውጪ ቁልፍ ስለሆነ፣ ይህንንም ለሬይልስ መንገር ይኖርብናል፡፡
ከላይ የተወያየናቸውን የተጠቃሚ/የትስስር ማሕበርን ተግባራዊ የማድረጉ ውጤት፣ በዝርዝር 14.2 እና በዝርዝር 14.3 ውስጥ ይታያል፡፡ የነዚህ ዝርዝሮች የመግለጫ ጽሑፉ ላይ እንደተመለከተው፣ ሁለቱም ላይ ፈተናው በአሁኑ ጊዜ ቀይ ነው (ለምን?)፤6 ይህንን ችግር በክፍል 14.1.3 ላይ እናስተካክለዋለን፡፡
has_many
) መተግበር፡፡ ቀይ app/models/teteqami.rb
class Teteqami < ApplicationRecord
has_many :achrtshufs, dependent: :destroy
has_many :nq_tssrs, class_name: "Tssr",
foreign_key: "teketay_id",
dependent: :destroy
.
.
.
end
(አንድ ተጠቃሚ ከውሂበጎታው በሚጠፋበት ወቅት፣ የተጠቃሚው ትስስሮች ሁሉ አብረውት ይጠፋ ዘንድ፣ ጥገኛ: :አጥፊን (dependent: :destroy
) በማሕበሩ ውስጥ አክለናል።)
belongs_to
) ማህበርን በትስስር ቅርጸቱ ላይ ማከል።ቀይ app/models/tssr.rb
class Tssr < ApplicationRecord
belongs_to :teketay, class_name: "Teteqami"
belongs_to :ktl, class_name: "Teteqami"
end
በውነቱ የ‘ክትል (ktl
) ማሕበሩ እስከ ክፍል 14.1.4 ድረስ አይፈለግም፤ ይሁን እንጂ ትይዩው የክትል መዋቅር ግልጽ የሚሆነው፣ ሁለቱንም ሕብረቶች በአንድ ላይ መተግበሩ ላይ የተመሰረተ ስለሆነ፣ እኛም እንደዛው አድርገናል።
በሰንጠረዥ 14.1 ውስጥ እንደሚታየው፣ በዝርዝር 14.2 እና በዝርዝር 14.3 ውስጥ ያሉት ትስስሮች፣ በሰንጠረዥ 13.1 ውስጥ ካየናቸው ጋር ተመሳሳይነት ያላቸው ዘዴዎችን ይሰጡናል።
ዘዴ | ጥቅም |
nq_tssr.teketay |
ተከታይን መመለስ |
nq_tssr.ktl |
ክትል ተጠቃሚን መመለስ |
teteqami.nq_tssrs.create(ktl_id: lela_teteqami.id) |
ከተጠቃሚው (teteqami ) ጋር የተዛመደ አንድ ንቁ ትስስርን መፍጠር |
teteqami.nq_tssrs.create!(ktl_id: lela_teteqami.id) |
ከተጠቃሚው (teteqami ) ጋር የተዛመደ አንድ ንቁ ትስስርን መፍጠር (በውድቀት ጊዜ ልዩነትን ያስነሳል) |
teteqami.nq_tssrs.build(ktl_id: lela_teteqami.id) |
ከተጠቃሚው (teteqami ) ጋር የተዛመደ አንድ አዲስ የትስስር ቁስን መመለስ |
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
create
) ዘዴን ከሰንጠረዥ 14.1 በመጠቀም፣ በውሂበጎታው ውስጥ የሚገኘውን የመጀመሪያውን ተጠቃሚ፣ ሁለተኛው ተጠቃሚ እንደሚከተለው አድርጉ።
nq_tssr.ktl
) እና የ‘ንቅ_ትስስር.ተከታይ (nq_tssr.teketay
) ዋጋዎች ትክክል መሆናቸውን አረጋግጡ፡፡
ከመቀጠላችን በፊት ሁሉንም ነገር የተሟላ ለማድረግ፣ አንዳንድ የትስስር ቅርጸት ማረጋገጫወችን እናክላለን፡፡ በዝርዝር 14.4 ውስጥ ያሉት ፈተናወች እና በዝርዝር 14.5 ውስጥ ያሉት የአፕልኬሽኑ ኮዶች በግልጽ የተቀመጡ ናቸው፡፡ በዝርዝር 6.30 ውስጥ ለተጠቃሚ እንደመነጨው እቃ ሁሉ፣ ለትስስር የመነጨው እቃም እንዲሁ፣ በተዛማጁ ፍልሰት ላይ የተጣለውን የልዩነትን ግዴታ ይጥሳል (ዝርዝር 14.1)፡፡ የዚህ መፍትሄም ልክ በዝርዝር 6.31 ውስጥ እንደተደረገው፣ የእቃ ይዘቶቹን ማስወገድ ይሆናል፤ ይህም በዝርዝር 14.6 ላይ ተተግብሯል፡፡
test/models/tssr_test.rb
require "test_helper"
class TssrTest < ActiveSupport::TestCase
def setup
@tssr = Tssr.new(teketay_id: teteqamis(:michael).id,
ktl_id: teteqamis(:ermias).id)
end
test "ብቁ መሆን አለበት" do
assert @tssr.valid?
end
test "አንድ teketay_id ን ማስፈለግ አለበት" do
@tssr.teketay_id = nil
assert_not @tssr.valid?
end
test "አንድ ktl_id ን ማስፈለግ አለበት" do
@tssr.ktl_id = nil
assert_not @tssr.valid?
end
end
app/models/tssr.rb
class Tssr < ApplicationRecord
belongs_to :teketay, class_name: "Teteqami"
belongs_to :ktl, class_name: "Teteqami"
validates :teketay_id, presence: true
validates :ktl_id, presence: true
end
test/fixtures/tssrs.yml
# ባዶ
በዚህ ወቅት የፈተና ስብስቡ አረንጓዴመሆን አለበት:-
$ rails test
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
አሁን የትስስር ማሕበሮች ልብ ወደሆኑት፤ ወደ ሚከተላቸው (miketelachew
) እና ወደ ተከታዮች (teketayoch
) ትስስሮች መጥተናል፡፡ እዚህ ላይ በ‘ብዙ_አለው በኩል (has_many :through
) የተባለውን የግንኙነት ዘዴ ለመጀመሪያ ጊዜ እንጠቀማለን፤ በምስል 14.7 ውስጥ በስእላዊ መግለጫ ላይ እንደተመለከተው፣ አንድ ተጠቃሚ በትስስሮች በኩል ብዙ የሚከተላቸው ይኖሩታል፡፡ አንድ የ‘ብዙ_አለው በኩል (has_many :through
) ማሕበርን ስንጠቀም፣ ሬይልስ ከአንድ ነጠላ ስም ጋር የሚዛመድ አንድ የውጪ ቁልፍ ማሕበርን በነባሪ መመልከት ይጀምራል፡፡ በሌላ አማርኛ ይህንን ከመሰለ ኮድ ላይ:-
has_many :ktls, through: :nq_tssrs
ሬይልስ “ktls” የሚለውን ጽሑፍ ይመለከት እና የዚህን ነጠላ “ktl” ብሎ በመቀየር በ‘ትስስሮች (tssrs
) ሰንጠረዥ ላይ ክትል_መታወቂያ‘ን (ktl_id
) በመጠቀም፣ አንድ ክምችትን ይፈጥራል ማለት ነው፡፡ ነገር ግን በክፍል 14.1.1 ላይ እንደተጠቀሰው፣ ተጠቃሚ.ክትሎች (teteqami.ktls
) የሚለውን፣ ለጆሮ ቀፋፊ የሆነውን ዘዴ ከመጠቀም ይልቅ፣ አንድ ተጠቃሚ.ሚከተላቸው (teteqami.miktelachew
) የተባለ ዘዴን እራሳችን እንጽፋለን፡፡ ሬይልስ በተፈጥሮው፣ በዚህ ሁኔታ ላይ የ‘ምንጪ (source
) ሰሚአሴትን በመጠቀም፣ (በዝርዝር 14.8 ላይ እንደሚታየው) ነባሪውን ስያሜ እንድናግድ ያስችለናል፣ ይህም ሬይልስን የ‘ሚከተላቸው (miketelachew
) የድርድር ምንጪ፣ የ‘ክትል (ktl
) መታወቂያዎች ክምችት መሆኑን በግልጽ/በቁምነገር ይነግረዋል፡፡
miketelachew
) ማሕበርን ማከል። app/models/teteqami.rb
class Teteqami < ApplicationRecord
has_many :achrtshufs, dependent: :destroy
has_many :nq_tssrs, class_name: "Tssr",
foreign_key: "teketay_id",
dependent: :destroy
has_many :miketelachew, through: :nq_tssrs, source: :ktl
.
.
.
end
በዝርዝር 14.8 ውስጥ የተበየነውን ማሕበር፣ ወደ አንድ ሃይለኛ የ‘ንቅ መዝገብ እና የድርድር አሰራርን ወደመሰለ፣ ጥምረት ወዳለው አመርቂ ባህሪ ያመራናል፡፡ ለምሳሌ፣ የ‘ያካትታልን? (include?
) ዘዴን በመጠቀም፣ የተከታዮች ክምችት ሌላውን ተጠቃሚ እንደያዘ ለማረጋገጥ ወይም በማሕበሩ በኩል ቁሶቹን ለመፈለግ ያስችለናል (ክፍል 4.3.1)፡-
teteqami.miketelachew.include?(lela_teteqami)
teteqami.miketelachew.find(lela_teteqami)
ልክ እንደ ማንኛውም ድርድር፣ የፈለገውን አባል ማከልም ሆነ መሰረዝ እንችላለን:-
teteqami.miketelachew << lela_teteqami
teteqami.miketelachew.delete(lela_teteqami)
(ይሄ <<
የአካፋ ስሌት የተሰጠውን ነገር፣ በድርድሩ መጨረሻ ላይ እንደሚጨምር በክፍል 4.3.1 ላይ እንደተመለከትን አስታውሱ፡፡)
በብዙ ሁኔታዎች ውጤታማ በሆነ መንገድ ሚከተላቸው‘ን (miketelachew
) እንደ አንድ ድርድር አድርገን ልንቆጥረው ብንችልም፣ ሬይልስ በስተጀርባ ነገሮችን እንዴት አድርጎ እንደሚያስተናግድ በጥሩ ሁኔታ ያውቃል። ለምሳሌ ይህንን የመሰለ ኮድ:-
miketelachew.include?(lela_teteqami)
እዚህ ላይ የ‘ያካትታልን? (include?
) ዘዴን ለመተግበር፣ ሁሉንም ተከታዮች ከውሂበጎታ የሚጎትት/የሚያወጣ ዓይነት ሊመስል ይችላል፣ ነገር ግን በውነቱ፣ ለቅልጣፌ ሲባል ሬይልስ ንጽጽሩ በቀጥታ በውሂበጎታው ውስጥ እንዲከናወን ያዘጋጃል፡፡ (ይህንን ሁኔታ በክፍል 13.2.1 ውስጥ ካለው ኮድ ጋር ስናነጻጽር፣ በዚያ ክፍል ላይ ይህ ኮድ:-
teteqami.achrtshufs.count
ቆጠራውን በቀጥታ በውሂበጎታው ውስጥ እንደሚያከናውን እናያለን፡፡)
የሚከተላቸው ትስስሮችን ለማንቀሳቀስ ተከተል (teketel
) እና አትከተል (atketel
) የተባሉ ሁለት መገልገያ (Utility) ዘዴወችን እናስተዋውቃለን፤7 ስለሆነም እንደዚህ አድርገን:- ተጠቃሚ.ተከተል(ሌላ_ተጠቃሚ) (teteqami.teketel(lela_teteqami)
) መጻፍ እንችላለን ማለት ነው፡፡ አንድ ተጠቃሚ ሌላውን እየተከተለ መሆኑን ለማረጋገጥ፣ አንድ ይከተላቸዋልን? (miketelachew?
) የተባለ ተዛማጅ የቡልየን ዘዴንም እናክላለን፡፡8
በመጀመሪያ የተወሰኑ ፈተናዎችን ለመጻፍ የምፈልግበት ትክክላኛ ሁኔታ ይሄ ነው፡፡ ምክንያቱም በአንድ የሚሰራ የድር በይነገጽ ላይ የሚከተላቸው ተጠቃሚዎችን ለማስገባት ገና ብዙ ጊዜ ስለሚቀረን እና እኛ ያበለጸግነው ኮድን ያለ አንድ ተገልጋይ (client) (በአሳሽ በኩል የሚገለገል ተጠቃሚ) ማካሄዱም ከባድ ስለሆነ ነው። በዚህ ሁኔታ ላይ፣ ተጠቃሚው የሌላውን ተጠቃሚ አለመከተሉን ለማረጋገጥ ይከተላቸዋልን? ‘ን (miketelachew?
) በመጠቀም፣ ሌላ ተጠቃሚን ለመከተል ተከተል‘ን (teketel
) በመጠቀም፣ ክንዋኔው የተሳካ መሆኑን ለማረጋገጥ ይከተላቸዋልን?‘ን (miketelachew?
) በመጠቀም እና በመጨረሻም አለመከተል (atketel
) እና እሱራሱ እንደሰራ የሚያረግጥ አንድ አጪር ፈተናን ለተጠቃሚ ቅርጸቱ መጻፉ ግን ቀላል ነው፡፡ ይህንን በተግባር ላይ በማዋል የተገኘው ውጤት፣ በዝርዝር 14.9 ውስጥ ይታያል። 9
test/models/teteqami_test.rb
require 'test_helper'
class TeteqamiTest < ActiveSupport::TestCase
.
.
.
test "አንድ ተጠቃሚን መከተል እና አለመከተል አለበት" do
michael = teteqamis(:michael)
ermias = teteqamis(:ermias)
assert_not michael.miketelachew?(ermias)
michael.teketel(ermias)
assert michael.miketelachew?(ermias)
michael.atketel(ermias)
assert_not michael.miketelachew?(ermias)
# ተጠቃሚዎች እራሳቸውን መከተል አይችሉም፡፡
michael.teketel(michael)
assert_not michael.miketelachew?(michael)
end
end
የ‘ሚከተላቸው (miketelachew
) ማሕበርን ልክ እንደ አንድ ድርድር አድርገን በመቁጠር፣ ተከተል (teketel
) ፣ አትከተል (atketel
) እና ይከተላቸዋልን?‘ን (miketelachew?
) የተባሉ የመገልገያ ዘዴወችን በዝርዝር 14.10 ላይ እንደሚታየው አድርገን መጻፍ እንችላለን፡፡ (በተጠቃሚ ቅርጸቱ ውስጥ የሚገኘውን የ‘ራሥ (self
) ተለዋዋጪን ማስወገድ አመች በሆነ ቁጥር እሱን ለማስወገድ ወደኋላ እንደማንል አስተውሉ።)
app/models/teteqami.rb
class Teteqami < ApplicationRecord
.
.
.
def qelabi
.
.
.
end
# አንድ ተጠቃሚን ይከተላል።
def teketel(lela_teteqami)
miketelachew << lela_teteqami unless self == lela_teteqami
end
# አንድ ተጠቃሚን አይከተልም።
def atketel(lela_teteqami)
miketelachew.delete(lela_teteqami)
end
# የአሁን ተጠቃሚ ሌላ ተጠቃሚን የሚከለው ከሆነ እውነትን ይመለሳል።
def miketelachew?(lela_teteqami)
miketelachew.include?(lela_teteqami)
end
private
.
.
.
end
በዝርዝር 14.10 ውስጥ ካለው ኮድ ጋር፣ ፈተናው አረንጓዴመሆን አለበት:-
$ rails test
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
የትስስሮች ስራን ለመቋጨት የመጨረሻ ተግባር የሚሆነው፣ ከ‘ተጠቃሚ.ሚከተላቸው (teteqami.miketelachew
) ዘዴ ጋር አብሮ የሚሄድ፣ አንድ ተጠቃሚ.ተከታዮች (teteqami.teketayoch
) የተባለ ዘዴን ማከል ብቻ ነው፡፡ አንድ የተከታዮች ድርድን ለማውጣት የሚያስፈልጉ መረጃዎች በሙሉ፣ ቀድሞውኑ በ‘ትስስሮች (tssrs
) ሰንጠረዥ ውስጥ እንደሚገኙ ከምስል 14.7 አስተውላችሁ ይሆናል። (ይህንንም በዝርዝር 14.2 ውስጥ ባለው ኮድ በኩል ልክ እንደ ንቅ_ትስስሮች (nq_tssrs
) ሰንጠረዥ አድርገን ተመልክተነው ነበር)፡፡ በእርግጥ የ‘ተከታይ_መታወቂያ (teketay_id
) ሚናን በ‘ክትል_መታወቂያ (ktl_id
) ሚና ከመቀየር እና በ‘ንቅ_ትስስሮች (nq_tssrs
) ቦታ ያልተካፈለ_ትስስሮች‘ን (yaltekafele_tssrs
) ከመተካት በስተቀር፤ አሰራሩ ከሚከተላቸው ተጠቃሚዎች አሰራር ጋር ፍጹም አንድ አይነት ነው። ስለሆነም የውሂብ ቅዱ በዝርዝር 14.9 ላይ እንደሚታየው ይሆናል ማለት ነው፡፡
በዝርዝር 14.12 ላይ እንደተመለከተው፣ የዝርዝር 14.9 የውሂብ ቅርጸት ትግበራ፣ ከዝርዝር 14.12 የውሂብ ቅርጸት ትግበራ ጋር በትክክል ትይዩ ነው፡፡
teteqami.teketayoch
) መተግበር። app/models/teteqami.rb
class Teteqami < ApplicationRecord
has_many :achrtshufs, dependent: :destroy
has_many :nq_tssrs, class_name: "Tssr",
foreign_key: "teketay_id",
dependent: :destroy
has_many :miketelachew, through: :nq_tssrs, source: :ktl
has_many :yaltekafele_tssrs, class_name: "Tssr",
foreign_key: "ktl_id",
dependent: :destroy
has_many :teketayoch, through: :yaltekafele_tssrs, source: :teketay
.
.
.
end
በዝርዝር 14.13 ውስጥ እንደሚታየው፣ የ‘ተከታዮች.ያካትታልን? (teketayoch.include?
) ዘዴን በመጠቀም፣ ከዚህ በላይ ያለውን የውሂብ ቅርጸት በሚመች ሁኔታ መፈተን እንችላለን፡፡ (ዝርዝር 14.13 ከ‘ይከተላቸዋልን? (miketelachew?
) ዘዴ ጋር የሚሄድ አንድ ተከትሏል_በ? (teketluwal_be?
) የተባለ ዘዴን ሊጠቀም ይችል ነበር፣ ነገር ግን ይህ ዘዴ በአፕልኬሽናችን ውስጥ የማያስፈልግ ሆኖ ተገኝቷል፡፡)
teketayoch
) መፈተን። አረንጓዴ test/models/teteqami_test.rb
require 'test_helper'
class TeteqamiTest < ActiveSupport::TestCase
.
.
.
test "አንድ ተጠቃሚን መከተል እና አለመከተል አለበት" do
michael = teteqamis(:michael)
ermias = teteqamis(:ermias)
assert_not michael.miketelachew?(ermias)
michael.teketel(ermias)
assert michael.miketelachew?(ermias)
assert ermias.teketayoch.include?(michael)
michael.atketel(ermias)
assert_not michael.miketelachew?(ermias)
end
end
ዝርዝር 14.13 በዝርዝር 14.9 ፈተናዎች ላይ አንድ መስመር ፈተናን ብቻ አክሏል፤ ነገር ግን በዝርዝር 14.12 ውስጥ ያለው ኮድ በቀላሉ የሚበላሽ ኮድ ስለሆነ፣ ፈተናው እንዲያልፍ ብዙ ነገሮች በትክክል መሰራት ይኖርባቸዋል፡፡
በዚህ ጊዜ የፈተና ስብስቡ በሙሉ አረንጓዴመሆን አለበት፡-
$ rails test
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
ተጠቃሚ
” ብላችሁ መሰየም ይኖርባችኋል)። የዚህ ተጠቃሚ.teketayoch.map(&:id)
ዋጋ ምንድንነው?
ተጠቃሚ.teketayoch.count
) ብዛት፣ እናንተ ከዚህ በላይ ከፈጠራችኋቸው ተከታዮች ብዛት ጋር እኩል መሆኑን አረጋግጡ፡፡
ተጠቃሚ.teketayoch.count
ለመጠቀም የተደረገው ተ.መ.ቋ ይሄን:- ተጠቃሚ.teketayoch.to_a.count
ለመጠቀም ከተደረገው ተ.መ.ቋ በምን ይለያል? ጠቃሚ ምንጪ:- ተጠቃሚው አንድ ሚሊየን ተከታዮች አሉት እንበል፡፡
ክፍል 14.1 ውስጥ የውሂብ ቅርጸት አቀራረጽ ክህሎታችንን የሚፈትኑ አንዳንድ ከባድ ምስፈርቶችን ጠይቆ ነበረ፣ እናም እነሱን በድንብ ለመረዳት፣ ትንሽ ጊዜ ወስዶባችሁ ከሆነ፣ ያ ጥሩ ምክንያት እንደሆነ ከወዲሁ ልትገነዘቡት ይገባል። በእርግጥ፣ ማሕበሮችን ለመረዳት ከሚረዱት ምርጥ መንገዶች ውስጥ አንዱ፣ በድር በይነገጽ ውስጥ እነሱን መጠቀም ነው፡፡
በዚህ ምዕራፍ መግቢያ ላይ አንድ ተጠቃሚ ሚከተላቸው የገጽ ፍሰት ቅድመዕይታን ተመልክተናል፡፡ በዚህ ክፍል ውስጥ፣ በእነዛ ስእላዊ መግለጫዎች ላይ ከተመለከቱት ውስጥ፣ ማለት መሰረታዊ የሆነ በይነገጽን፣ የሚከተላቸው እና የተከታዮች ተግባሮችን እንተገብራለን። ተጠቃሚ ሚከተላቸው እና የተጠቃሚ ተከታዮች ድርድሮችን ለማሳየት የሚያገለግሉ ሁለት የተለያዩ ገጾችንም እንሰራለን፡፡ በክፍል 14.3 ውስጥ፣ በማሳያ አፕልኬሽኑ ላይ የተጠቃሚ ሁኔታ ቀላቢውን በማከል፣ የማሳያ አፕልኬሽኑን ሙሉ በሙሉ እናጠናቅቃለን።
እንደቀድሞዎቹ ምዕራፎች ሁሉ፣ ውሂበጎታውን በናሙና ትስስሮች ለመሙላት፣ የ‘ሬይልስ ውሂብጎታ:ዝራ (rails db:seed
) ትእዛዝን መጠቀሙን፣ አሁንም ምቹ ሆኖ እናገኘዋለን፡፡ ይህ ከፊት ያለውን የድር ገጻችንን እይታ እና ስሜታ ለመንደፍ ያስችለናል፣ የደጀኑን አተገባበር ደግሞ በዚህ ክፍል መጨረሻ ላይ እንመለከታለን፡፡
የሚከተላቸው ትስስሮችን የሚዘራው ኮድ፣ በዝርዝር 14.14 ውስጥ ይታያል፡፡ የመጀመሪያውን ተጠቃሚ፣ ከሶስተኛው (3) እስከ ሃምሳ አንደኛው ያሉ ተጠቃሚወችን እንዲከተል ስናደርግ፣ እሱን ደግሞ ከአራተኛው (4) እስከ አርባ አንደኛው (41) ያሉ ተጠቃሚወች እንዲከተሉት አድርገናል፡፡ ከዚህ የሚገኙት ትስስሮች የአፕልኬሽኑን በይነገጽ ለማበልጸግ በቂ ይሆናሉ፡፡
db/seeds.rb
# አንድ ዋና የናሙና ተጠቃሚን መፍጠር።
Teteqami.create!(sim: "Abnetawi Teteqami",
emelekt: "example@railstutorial.org",
password: "kebekasa",
password_confirmation: "kebekasa",
astedadari: true,
nq: true,
nq_at: Time.zone.now)
# መአት ተጠቃሚዎችን ማመንጨት።
99.times do |n|
sim = Faker::Name.name
emelekt = "msalie-#{n+1}@railstutorial.org"
password = "mehlefeqal"
Teteqami.create!(sim: sim,
emelekt: emelekt,
password: password,
password_confirmation: password,
nq: true,
nq_at: Time.zone.now)
end
# ለክፍለንዑስ ተጠቃሚዎች አጪርጽሑፎችን ያመነጫል።
teteqamis = Teteqami.order(:created_at).take(6)
50.times do
yizet = Faker::Lorem.sentence(word_count: 5)
teteqamis.each { |teteqami| teteqami.achrtshufs.create!(yizet: yizet) }
end
# የመከተል ትስስሮችን ይፈጥራል።
teteqamis = Teteqami.all
teteqami = teteqamis.first
miketelachew = teteqamis[2..50]
teketayoch = teteqamis[3..40]
miketelachew.each { |ktl| teteqami.teketel(ktl) }
teketayoch.each { |teketay| teketay.teketel(teteqami) }
በዝርዝር 14.14 ውስጥ ያለውን ኮድ ለማስፈጸም፣ እንደተለመደው ውሂበጎታውን በድጋሜ እናስጀምር እና በድጋሜ እንዘራዋለን:-
$ rails db:migrate:reset
$ rails db:seed
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
Teteqami.first.teketayoch.count
ውጤት በዝርዝር 14.14 ከሚጠበቀው ዋጋ ጋር መዛመዱን አረጋግጡ፡፡
Teteqami.first.miketelachew.count
ትክክል መሆኑንም አረጋግጡ፡፡
አሁን የናሙና ተጠቃሚዎቻችን፣ ተጠቃሚዎችን በማስከተል እና በመከተል ላይ ስለሚገኙ፣ ይህንን ለማንጸባረቅ፣ የመገለጫ እና የመነሻ ገጹን ማዘመን ይኖርብናል፡፡ በመገለጫ እና በመነሻ ገጹ ላይ፣ የሚከተላቸው እና የተከታዮች አሃዛዊ-መረጃዎችን ለማሳየት የሚያገለግ አንድ ከፊልን በመስራት እንጀምራለን፡፡ በመቀጠል አንድ የተከተል/አትከተል ቅጽን እናክል እና ከዚያ፣ “ሚከተላቸው/ሏት” እና “ተከታዮች” ‘ን ለማሳየት የተመደቡ ሁለት ገጾችን እንሰራለን፡፡
በክፍል 14.1.1 ላይ እንደተገለጸው፣ የትዊተር ደንብን በመከተል፣ አንድ ተጠቃሚ የሚከተላቸውን ተጠቃሚዎች “ሚከተላቸው/ሏት” የሚለውን ቃል እንደ አንድ መሰየሚያ አድርገን እንጠቀማለን፡፡ ለምሳሌ “50 ሚከተላቸው/ሏት” ስንል ተጠቃሚው ሌሎች 50 ተጠቃሚዎችን እየተከተለ ነው ማለት ነው፡፡ አጠቃቀሙ ከዝርዝር 14.1 ጀምሮ በተርታ በተዘረዘሩት ስእላዊ መግለጫወች ላይ ሲታይ፣ አሁን ደግሞ በቅርበት ጎልቶ፣ በዝርዝር 14.10 ላይ ይታያል፡፡
በዝርዝር 14.10 ላይ ያሉት የአሃዛዊ-መረጃዎች፣ የአሁኑ ተጠቃሚ የሚከተላቸው እና የተከታዮቹን ተጠቃሚዎች የቁጥር ብዛትን የያዙ ሲሆን፤ እያንዳንዳቸውም ወደ ሚመለከታቸው ማሳያ ገጽ የተመደበ አንድ አገናኝ መሆን ይኖርባቸዋል፡፡ በምዕራፍ 5 ላይ እነዚህን አገናኞች በ '#'
ምልክት ቆርጠናቸው ነበር፣ በዛን ጊዜ እንደዛ ያደረግነው ስለ ማዘዋወርያዎች ጠለቅ ያለ ዕውቀት እና ልምድ ባልነበረን ወቅት ነበር፡፡ በዚህ ጊዜ፣ ለዚህ ስራ የሚያስፈልጉትን ትክክለኛ ገጾች የመስራቱን ሂደት ወደ ክፍል 14.2.3 ያስተላለፍን ቢሆንም፣ በዝርዝር 14.15 ላይ እንደሚታየው፣ ማዘዋወርዎቹን ግን አሁን እንሰራለን፡፡ ይህ ኮድ አንድ የ‘ሃብቶች (resources
) ጥምር ውስጥ የ‘:አባል (:member
) ዘዴን ይጠቀማል፣ ይህን ኮድ ከዚህ በፊት አላየነውም፣ እስኪ ግን ምን እንደሚሰራ መገመት ትችሉ ከሆነ ሞክሩ፡፡
miketelachew
) እና የ‘ተከታዮች (teketayoch
) ተግባሮችን ማከል። 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 do
member do
get :miketelachew, :teketayoch
end
end
resources :meleya_magberyas, only: [:edit]
resources :meda_masjemers, only: [:new, :create, :edit, :update]
resources :achrtshufs, only: [:create, :destroy]
end
ዓ.አ.ሃ.አው ለሚከተላቸው እና ለተከታዮች /ተጠቃሚዎች/1/ሚከተላቸው‘ን (/teteqamis/1/miketelachew) እና /ተጠቃሚዎች/1/ተከታዮች‘ን (/teteqamis/1/teketayoch) ሊመስል እንደሚችል ልትገምቱት ችላላችሁ፣ በዝርዝር 14.15 ላይ ያለው ኮድ በትክክል የሚያዘጋጀውም ይህንኑ ነው፡፡ ሁለቱም ገጾች ውሂብን ስለሚያሳዩ ትክክለኛው የሃ.ጽ.ማ.ስ ግስ አንድ የ‘ዓግኝ (GET)
መጠይቅ ነው፣ ስለሆነም ዓ.አ.ሃ.አወቹ ተገቢውን ምላሽ እንዲሰጡ ለማዘጋጀት የ‘አግኝ (get
) ዘዴን ተጠቅመናል። ይህ በእንዲህ እንዳለ፣ የ‘አባል (member
) ዘዴ የተጠቃሚውን መታወቂያ የያዙ ዓ.አ.ሃ.አች ላይ ምላሽ እንዲሰጡ ማዘዋወርያዎቹን ያዘጋጃል። ሌላኛው ያለ መታወቂያ የሚሰራው አማራጪ ስብስብ (collection
) ነው፤ ስለሆነም ይሄ:-
resources :teteqamis do
collection do
get :walya
end
end
የሚመልሰው የ‘/ተጠቃሚዎች/ዋልያ (/teteqamis/walya) ዓ.አ.ሃ.አን ይሆናል (በዚህ ምሳሌ መሰረት፣ አፕልኬሽኑ ውስጥ ያሉትን ሁሉንም ዋልያወች ያሳየናል ማለት ነው፡፡)10
በዝርዝር 14.15 አማካኝነት የመነጩት ማዘዋወሪያወች፣ በሰንጠረዥ 14.2 ላይ ይታያሉ፡፡ የሚከተላቸው እና የተከታዮች ተጠቃሚ ገጾችን ለማቅረብ በቅርቡ ስራ ላይ የምናውላቸውን፣ ስዩም ማዘዋወሪያወችን እንደያዙ በደንብ ተገንዝባችሁ ይሆናል።
የሃ.ጽ.ማ.ስ መጠይቅ | ዓ.አ.ሃ.አ | ጥቅም | ስዩም ማዘዋወሪያ |
GET |
/teteqamis/1/miketelachew | miketelachew |
miketelachew_teteqami_path(1) |
GET |
/teteqamis/1/teketayoch | teketayoch |
teketayoch_teteqami_path(1) |
የሚያስፈልጉትን ማዘዋወሪያወች በይነናል፣ አሁን የአሃዛዊ-መረጃዎች ከፊልን ለመበየን የሚያስችል አንድ አቋም ላይ እንገኛለን፣ ይህም በዝርዝር 14.16 ላይ እንደሚታየው፣ ሁለት አገናኞችን በአንድ የሃ.ጽ.መ.ቋ ክፍሊት ውስጥ ማድረግን ያሳትፋል፡፡
app/views/gru/_ahazawimerejawech.html.erb
<% @teteqami ||= ahun_teteqami %>
<div class="አሃዛዊመረጃዎች">
<a href="<%= miketelachew_teteqami_path(@teteqami) %>">
<strong id="ሚከተላቸው" class="አሃዛዊመረጃ">
<%= @teteqami.miketelachew.count %>
</strong>
ሚከተላቸው/ሏት
</a>
<a href="<%= teketayoch_teteqami_path(@teteqami) %>">
<strong id="ተከታዮች" class="አሃዛዊመረጃ">
<%= @teteqami.teketayoch.count %>
</strong>
ተከታዮች
</a>
</div>
በተጠቃሚ ማሳያ እና በመነሻ ገጹ ላይ፣ አሃዛዊ-መረጃዎችን የምናካትት ስለሆነ፣ በዝርዝር 14.16 ላይ ያለው የመጀመሪያው መስመር ይህንን በመጠቀም:-
<% @teteqami ||= ahun_teteqami %>
ትክክለኛውን ገጽ ይመርጣል፡፡ በሳጥን 8.1 እንደተብራራው፣ @ተጠቃሚ (@teteqami
) (በመገለጫ ገጹ ላይ እንዳለው) ምንም (nil
) በማይሆንበት ጊዜ ምንም አያደርግም፤ ግን (በመነሻ ገጹ ላይ እንዳለው) በሚሆንበት ጊዜ @ተጠቃሚ‘ን (@teteqami
) ለአሁኑ ተጠቃሚ ያዘጋጀዋል፡፡ እንዲሁም የሚከተላቸው/የተከታዮች ቆጠራዎች በማሕበሩ በኩል:-
@teteqami.miketelachew.count
እና
@teteqami.teketayoch.count
‘ን በመጠቀም እንደሚሰሉ አስተውሉ፡፡ እነዚህን በዝርዝር 13.24 ውስጥ የአጪርጽሑፎች ብዛትን እንዲቆጥርልን እንደዚህ ብለን:-
@teteqami.achrtshufs.count
ከጻፍነው ኮድ ጋር አነጻጽሩ፡፡ በአጪርጽሑፎቹ ሁኔታ ላይ፣ ሬይልስ ለቅልጥፍና ቆጠራውን በቀጥታ በውሂበጎታው ውስጥ ያከናውናል፡፡
አንድ መጨረሻ ላይ ልብ ሊባል የሚገባው ዝርዝር፣ በአንዳንድ አባል ላይ የቅ.ቋ መታወቂያዎች መኖራቸው ነው፣ እንደዚህኛው ማለት ነው:-
<strong id="ሚከተላቸው" class="አሃዛዊመረጃ">
...
</strong>
ይህ በክፍል 14.2.5 ውስጥ ለኤጃክስ (Ajax) መተግበሪያ ጥቅም ላይ የሚውል ሲሆን፣ ይህም ልዩ መታወቂያቸውን በመጠቀም በገጹ ላይ የሚገኙትን አባላት ይደርሳል።
ከፊሉን ከሰነቁ በኋላ፣ በዝርዝር 14.17 ላይ እንደተመለከተው፣ አሃዛዊ-መረጃዎቹን በመነሻ ገጹ ላይ ማካተቱ ቀላል ነው፡፡
app/views/quami_getss/menesha.html.erb
<% if gebtual? %>
<div class="row">
<aside class="col-md-4">
<section class="የተጠቃሚ_መረጃ">
<%= render 'gru/teteqami_mereja' %>
</section>
<section class="አሃዛዊመረጃዎች">
<%= render 'gru/ahazawimerejawech' %>
</section>
<section class="የአጪርጽሑፍ_ቅጽ">
<%= render 'gru/achrtshuf_qts' %>
</section>
</aside>
<div class="col-md-8">
<h3>አጪርጽሑፍ ቀላቢ</h3>
<%= render 'gru/qelabi' %>
</div>
</div>
<% else %>
.
.
.
<% end %>
በዝርዝር 14.18 ላይ እንደሚታየው፣ አሃዛዊ-መረጃዎችን ቅጥ ለማስያዝ፣ የተወሰኑ ዓ.ቆ.ሉ.ቅን እናክላለን (ይህ ዝርዝር፣ በዚህ ምዕራፍ ውስጥ የሚያስፈልጉትን ማለት ሁሉንም የቅጠሉህ ኮዶችን የያዘ ነው)። የተገኘው የመነሻ ገጽ ውጤት በምስል 14.11 ላይ ይታያል።
app/assets/stylesheets/bju.scss
.
.
.
/* ጎን-አሞሌ */
.
.
.
.አምሳያ {
float: left;
margin-right: 10px;
}
.አምሳያ_እርምት {
margin-top: 15px;
}
.አሃዛዊመረጃዎች {
overflow: auto;
margin-top: 0;
padding: 0;
a {
float: left;
padding: 0 10px;
border-left: 1px solid $gray-lighter;
color: gray;
&:first-child {
padding-left: 0;
border: 0;
}
&:hover {
text-decoration: none;
color: blue;
}
}
strong {
display: block;
}
}
.የተጠቃሚ_አምሳያወች {
overflow: auto;
margin-top: 10px;
.አምሳያ {
margin: 1px 1px;
}
a {
padding: 0;
}
}
.ተጠቃሚዎች.ተከተል {
padding: 0;
}
/* ቅጾች */
.
.
.
በመገለጫ ገጹ ላይ፣ አሃዛዊ-መረጃዎችን ማቅረቡን በአጪር ጊዜ ውስጥ እንመለስበታለን፣ ነገር ግን በቅድሚያ በዝርዝር 14.19 ላይ እንደሚታየው፣ ለተከተል እና ለአትከተል አዝራር የሚሆን አንድ ከፊልን እንሰራለን፡፡
app/views/teteqamis/_teketel_qts.html.erb
<% unless ahun_teteqami?(@teteqami) %>
<div id="የተከተል_ቅጽ">
<% if ahun_teteqami.miketelachew?(@teteqami) %>
<%= render 'atketel' %>
<% else %>
<%= render 'teketel' %>
<% end %>
</div>
<% end %>
ይህ ትክክለኛውን ስራ ወደ ተከተል (teketel
) እና አትከተል (atketel
) ከፊሎች ከማመላከት በስተቀር ሌላ ምንም ነገር አያደርግም፣ ይህም በዝርዝር 14.20 ውስጥ እንደሚታየው፣ የአጪርጽሑፎች ሃብት ምሳሌን (ዝርዝር 13.30) የሚከተል፣ አዲስ የትስስሮች ሃብት ማዘዋወርያዎችን ይፈልጋል።
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 do
member do
get :miketelachew, :teketayoch
end
end
resources :meleya_magberyas, only: [:edit]
resources :meda_masjemers, only: [:new, :create, :edit, :update]
resources :achrtshufs, only: [:create, :destroy]
resources :tssrs, only: [:create, :destroy]
end
የተከተል/አትከተል ከፊሎቹ በዝርዝር 14.21 እና በዝርዝር 14.22 ላይ ይታያሉ፡፡
app/views/teteqamis/_teketel.html.erb
<%= form_with(model: ahun_teteqami.nq_tssrs.build, local: true) do |ቅ| %>
<div><%= hidden_field_tag :ktl_id, @teteqami.id %></div>
<%= ቅ.submit "ተከተል", class: "btn btn-primary" %>
<% end %>
app/views/teteqamis/_atketel.html.erb
<%= form_with(model: ahun_teteqami.nq_tssrs.find_by(ktl_id: @teteqami.id),
html: { method: :delete }, local: true) do |ቅ| %>
<%= ቅ.submit "አትከተል", class: "btn" %>
<% end %>
እነዚህ ሁለት ቅጾች፣ የአንድ ትስስር ቅርጸት ቁስን ለማንቀሳቀስ፣ ሁለቱም ቅጽ_ጋር‘ን (form_with
) ይጠቀማሉ፤ በሁለቱ መካከል ያለው ዋና ልዩነት፣ ዝርዝር 14.21 አንድ አዲስ ትስስርን መገንባቱ ሲሆን፣ ዝርዝር 14.22 ደግሞ አሁን ያለውን ትስስር መፈሉጉ ነው፡፡ በተፈጥሮ የመጀመሪያው፣ አንድ አዲስ ግንኙነትን ለመፍጠር (create
) ለትስስሮች መቆጣጠርያው፣ አንድ የ‘ዓስቀምጥ (POST)
መጠይቅን የሚልክ ሲሆን፤ ሁለተኛው ግን ትስስሩን ለመሠረዝ አንድ የ‘ሠርዝ (DELETE)
መጠይቅን ለ‘አጥፋ (destroy
) ይልካል፡፡ (እነዚህን ተግባሮች በክፍል 14.2.4 ላይ እንጽፋቸዋለን።) በመጨረሻም፣ የመከተል ቅጽ ካለ አንድ አዝራር በስተቀር ሌላ ምንም አይነት ይዘት እንደለለው አስተውላችሁ ይሆናል፣ ይሁን እንጅ አሁንም የ‘ክትል_መታወቂያ‘ውን (ktl_id
) ወደ መቆጣጠሪያው መስደድ ይፈልጋል፡፡ ይህንን ለማከናወን በዝርዝር 14.21 ውስጥ አንድ የ‘ተደበቀ_መስክ_መለያ (hidden_field_tag
) ዘዴን ተጠቅመናል፤ ይህ ዘዴም የሚከተለውን የሃ.ጽ.መ.ቋ ቅጽን ይሰራል:-
<input id="ktl_id" name="ktl_id" type="hidden" value="3" />
በክፍል 12.3 ውስጥ እንዳየነው (ዝርዝር 12.14)፣ የተደበቀው የ‘ግብዓት (input
) መለያ በቅጹ ውስጥ የገባውን ዋጋ በአሳሹ ላይ ሳያሳይ፣ በገጹ ውስጥ ተገቢውን መረጃ ይይዛል፡፡
በዝርዝር 14.23 ውስጥ እንደሚታየው፣ አሁን ከፊሎችን በማቅረብ፣ የተከተል ቅጹን እና የተከታይ አሃዛዊ-መረጃወቹን፣ በተጠቃሚው መገለጫ ገጽ ላይ በቀላሉ ማካተት እንችላለን። የ “ተከተል” እና የ “አትከተል” አዝራሮች ያሏቸው የመገለጫ ገጾች በምስል 14.12 እና በምስል 14.13 ላይ በቅደም ተከተል ይታያሉ፡፡
app/views/teteqamis/show.html.erb
<% provide(:title, @teteqami.sim) %>
<div class="row">
<aside class="col-md-4">
<section class="የተጠቃሚ_መረጃ">
<h1>
<%= amsaya_le @teteqami %>
<%= @teteqami.sim %>
</h1>
</section>
<section class="አሃዛዊመረጃዎች">
<%= render 'gru/ahazawimerejawech' %>
</section>
</aside>
<div class="col-md-8">
<%= render 'teketel_qts' if gebtual? %>
<% if @teteqami.achrtshufs.any? %>
<h3>(<%= @teteqami.achrtshufs.count %>) አጪርጽሑፎች</h3>
<ol class="አጪርጽሑፎች">
<%= render @achrtshufs %>
</ol>
<%= will_paginate @achrtshufs, :previous_label => "ቀዳሚ",
:next_label => "ቀጣይ" %>
<% end %>
</div>
</div>
በቅርብ ጊዜ ውስጥ እነዚህ አዝራሮች መስራት እንዲጀምሩ እናደርጋቸዋለን፣ በርግጥ፣ በሁለት ዓይነት መንገድ እንደሚሰሩም እናደርጋቸዋለን፣ አንደኛው በመደበኛው መንገድ ሲሆን (ክፍል 14.2.4)፣ ሁለተኛው ደግሞ ኤጃክስን በመጠቀም ይሆናል (ክፍል 14.2.5)፣ በመጀመሪያ ግን የሃ.ጽ.መ.ቋ በይነገጹን በሚከተሉት እና በተከታዮች ገጽ ላይ ሰርተን መጨረስ ይኖርብናል።
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
የሚከተሉ እና ተከታዮችን ለማሳየት የምንጠቀምበት ገጽ፣ ከተጠቃሚ መገለጫ፣ ከተጠቃሚዎች ማውጫ ገጽ (ክፍል 10.3.1)፣ ከአንድ የተጠቃሚ መረጃ የጎን-አሞሌ (የሚከተሉት የአሃዛዊ-መረጃወችን ጨምሮ) እና ከተጠቃሚዎች ዝርዝር ጋር የተዳቀለ አንድ ገጽን ይመስላል። በተጨማሪም፣ በጎን-አሞሌው ውስጥ አንድ መጠኑ ያነሰ፣ አነስተኛ የተጠቃሚ መገለጫ ምስል አገናኝን እናካትታለን፡፡ እነዚህን መስፈርቶች የሚያሟሉ ስእላዊ መግለጫወች፣ በምስል 14.14 (የሚከተሉ) እና በምስል 14.15 ላይ (የተከታዮች) ይታያሉ፡፡
የመጀመሪያ ሂደታችን የሚከተላቸው/ሏት እና የተከታዮች አገናኞችን እንዲሰሩ ማድረግ ይሆናል፡፡ የትዊተርን የአሰራር ስልት በመከተል፣ ሁለቱንም ገጾች የተጠቃሚ መግባትን እንዲፈልጉ እናደርጋቸዋለን። ልክ እንደ አብዛኛዎቹ ቀደምት የመዳረሻ ቁጥጥር ምሳሌዎች ላይ እንዳደረግነው ሁሉ፣ አሁንም በዝርዝር 14.24 ላይ እንደሚታየው፣ ለነሱ አንዳንድ ፈተናዎችን በመጻፍ እንጀምራለን፡፡ ዝርዝር 14.24 ከሰንጠረዥ 14.2 ላይ የሚገኙትን ስዩም ማዘዋወሪያወችን እንደሚጠቀም አስተውሉ፡፡
test/controllers/teteqamis_controller_test.rb
require 'test_helper'
class TeteqamisControllerTest < ActionDispatch::IntegrationTest
def setup
@teteqami = teteqamis(:michael)
@lela_teteqami = teteqamis(:ermias)
end
.
.
.
test "ባልተገባ ጊዜ ሚከተላቸው ማዟዟር አለበት" do
get miketelachew_teteqami_path(@teteqami)
assert_redirected_to gba_url
end
test "ባልተገባ ጊዜ ተከታዮች ማዟዟር አለበት" do
get teketayoch_teteqami_path(@teteqami)
assert_redirected_to gba_url
end
end
የአተገባበሩ ብቸኛው አስቸጋሪ ክፍል፣ በተጠቃሚዎች መቆጣጠሪያው ውስጥ ሁለት አዲስ ተግባሮችን ማከል እንዳለብን መገንዘቡ ነው። በዝርዝር 14.15 ላይ በተበየኑት ማዘዋወሪያወች ላይ በመመርኮዝ፣ ሚከተላቸው (miketelachew
) እና ተከታዮች (teketayoch
) ብለን ልንጠራቸው ይገባል፡፡ እያንዳንዱ ተግባር፣ አንድ ርዕስ ማዘጋጀት፣ ተጠቃሚውን መፈለግ፣ እና ወይ በ‘@ተጠቃሚ.ሚከተላቸው (@teteqami.miketelachew
) አለበለዚያ ደግሞ በ‘@ተጠቃሚ.ተከታዮች (@teteqami.teketayoch
) ፈልጎ (ማለት ከገጸቁጥር ጋር) በማውጣት ገጹን ማቅረብ አለበት። ውጤቱም በዝርዝር 14.25 ይታያል፡፡
miketelachew
) እና የ‘ተከታዮች (teketayoch
) ተግባራትን ማከል። ቀይ app/controllers/teteqamis_controller.rb
class TeteqamisController < ApplicationController
before_action :gb_teteqami, only: [:index, :edit, :update, :destroy,
:miketelachew, :teketayoch]
.
.
.
def miketelachew
@title = "ሚከተላቸው/ሏት"
@teteqami = Teteqami.find(params[:id])
@teteqamis = @teteqami.miketelachew.paginate(page: params[:page])
render 'teketay_asay'
end
def teketayoch
@title = "ተከታዮች"
@teteqami = Teteqami.find(params[:id])
@teteqamis = @teteqami.teketayoch.paginate(page: params[:page])
render 'teketay_asay'
end
private
.
.
.
end
በዚህ ስልጠና ሁሉ እንደተመለከትነው፣ የተለመደው የሬይልስ አሰራር፣ አንድ ከተግባሩ ጋር የሚዛመድ ዝግጁገጽታን በግልጽ (implicitly) ማቅረብ ነው፤ ለምሳሌ፣ የ‘አሳይ (show
) ተግባር ልክ መጨረሻ ላይ አሳይ.ሃጽመቋ.ክሩ‘ን (show.html.erb
) እንዲቀርብ ያደርጋል፡፡11 በተቃራኒው፣ በዝርዝር 14.25 ውስጥ ያሉ ሁለቱም ተግባሮች ተከታይ_አሳይ (teketay_asay
) የተባለ ትይታን ለማቅረብ፣ ለ‘ዓቅርብ (render
) ዘዴ፣ አንድ ያልተገለጸ (Explicit) ጥሪን ያደርጋሉ፣ ይህንን ትይታም ግዴታ መፍጠር ይኖርብናል። የጋራ የሆነ አንድ ትይታ የሚጠቀሙበት ምክንያት ደግሞ፣ በሁለቱም ሁኔታ ላይ ክትሩቢው በጣም ተመሳሳይ ስለሆነ ነው፣ እናም ዝርዝር 14.26 ሁለቱንም ይሸፍንልናል፡፡
teketay_asay
) ትይታ። አረንጓዴ app/views/teteqamis/teketay_asay.html.erb
<% provide(:title, @title) %>
<div class="row">
<aside class="col-md-4">
<section class="የተጠቃሚ_መረጃ">
<%= amsaya_le @teteqami %>
<h1><%= @teteqami.sim %></h1>
<span><%= link_to "መገለጫዎን ይመልከቱ", @teteqami %></span>
<span><b>አጪርጽሑፎች:</b> <%= @teteqami.achrtshufs.count %></span>
</section>
<section class="አሃዛዊመረጃዎች">
<%= render 'gru/ahazawimerejawech' %>
<% if @teteqamis.any? %>
<div class="የተጠቃሚ_አምሳያወች">
<% @teteqamis.each do |teteqami| %>
<%= link_to amsaya_le(teteqami, meten: 30), teteqami %>
<% end %>
</div>
<% end %>
</section>
</aside>
<div class="col-md-8">
<h3><%= @title %></h3>
<% if @teteqamis.any? %>
<ul class="ተጠቃሚዎች ተከተል">
<%= render @teteqamis %>
</ul>
<%= will_paginate :previous_label => "ቀዳሚ", :next_label => "ቀጣይ" %>
<% end %>
</div>
</div>
በዝርዝር 14.25 ውስጥ ያሉት ተግባሮች በዝርዝር 14.26 ውስጥ ባሉት ሁለት ሁኔታዎች ላይ በመርኮዝ ሁለት ትይታወችን ያቀርባሉ፡፡ ምስል 14.16 የ “ሚከተላቸው/ሏት” ትይታን ሲያቀርብ፣ ምስል 14.17 ደግሞ የ “ተከታዮች” ትይታን ያቀርባል፡፡ ከላይ ያለው ኮድ፣ ማናቸውም ቦታ ላይ፣ የአሁን ተጠቃሚን እንዳልተጠቀመ አስተውሉ፤ ስለሆነም በምስል 14.18 ላይ እንደሚታየው፣ እነዚሁ አገናኞች ለሌሎች ተጠቃሚዎችም ይሰራሉ፡፡
በዚህ ጊዜ፣ በዝርዝር 14.25 ውስጥ ባለው በቅድመአጣሪው ምክንያት በዝርዝር 14.24 ውስጥ ያሉ ፈተናወች አረንጓዴ መሆን አለባቸው:-
$ rails test
የ‘ተከታይ_አሳይ (teketay_asay
) አቅርቦትን ለመፈተን፣ ማለት የሚሰሩ የሚከተላቸው እና የተከታዮች ገጾች መኖራቸውን ለማረጋገጥ፣ አንዳንድ አጪር የውህደት ፈተናወችን እንጽፋለን። ፈተናወቹም እውነታን ለማጣራት የተነደፉ እንጂ፣ የተሟላ ፈተናን እንዲያደርጉ የተነደፉ አይደሉም፤ በእርግጥ በክፍል 5.3.4 ላይ እንደተብራራው፣ እንደ ሃ.ጽ.መ.ቋ አወቃቀር ያሉ ነገሮች ላይ አጠቃላይ የሆነ ፈተናን ማድረጉ፣ በቀላሉ ሊበላሽ ወደሚችል ሁኔታ ሊያመራ እና የልታሰበ ውጤትን ሊያስከትል ይችላል፡፡ በሚከተላቸው እና በተከታዮች ገጾች ላይ እቅዳችን፣ ቁጥራቸው በትክክል መታየቱን እና አገናኞቹ ከትክክለኛ ዓ.አ.ሃ.አ‘ዎች ጋር በገጹ ላይ እንደሚታዩ ማረጋገጥ ነው፡፡
ስራችንን ለመጀመር እንደተለመደው፣ አንድ የውህደት ፈተናን እናመነጫለን፡-
$ rails generate integration_test miketelachew
invoke test_unit
create test/integration/miketelachew_test.rb
በመቀጠልም፣ የተወሰኑ የፈተና ውሂቦችን ማሰባሰብ ይኖርብናል፣ ይህንንም የሚከተሉት እና የተከታዮች ትስስሮችን ለመፍጠር አንዳንድ የትስስሮች እቃዎችን በማከል ማከናወን እንችላለን፡፡ ከአንድ የተሰጠ ተጠቃሚ ጋር አንድ አጪርጽሑፍን ለማገናኘት እንደዚህ:-
weba:
yizet: "ወባ ፊት የነሳው ሰውየ ቡዳ እንዳይበላኝ አለ።"
created_at: <%= 10.minutes.ago %>
teteqami: michael
ያለ ኮድን መጠቀም እንደምንችል በክፍል 13.2.3 ላይ እንደተማርን አስታውሱ፡፡ በተለይ ደግሞ ይህን ከመጻፍ:-
teteqami: michael
ይልቅ ይህንን:-
teteqami_id: 1
መጻፍ እንደምንችልም ተገንዝባችሁ ይሆናል፡፡ ይህንን ሃሳብ በትስስሮች እቃዎች ላይ መተግበሩ፣ በዝርዝር 14.28 ውስጥ የሚገኘውን ማሕበር ይሰጣል፡፡
test/fixtures/tssrs.yml
and:
teketay: michael
ktl: gerie
hulet:
teketay: michael
ktl: abeba
sost:
teketay: gerie
ktl: michael
arat:
teketay: ermias
ktl: michael
በዝርዝር 14.28 ውስጥ ያሉት የመጀመሪያዎቹ እቃዎች፣ ማይክልን፣ ገሬን እና አበባን እንዲከተል ያዘጋጃሉ፣ ከዚያ ማይክልን፣ ገሬ እና ኤርምያስ እንዲከተሉት ያዘጋጃሉ፡፡ ትክክለኛውን ቆጠራ ለማረጋገጥ፣ በተጠቃሚ የመገለጫ ገጽ ላይ የአጪርጽሑፎች ብዛት መታየቱን ለመፈተሽ፣ በዝርዝር 13.28 ውስጥ የተጠቀምንበትን የ‘አቻነት_አረጋግጥ (assert_match
) ዘዴን መጠቀም እንችላለን፡፡ ለትክክለኞቹ አገናኞች፣ ማረጋገጫዎችን ማከሉ፣ በዝርዝር 14.29 ውስጥ የተመለከቱትን ፈተናወች ያስገኛል፡፡
test/integration/miketelachew_test.rb
require "test_helper"
class MiketelachewTest < ActionDispatch::IntegrationTest
def setup
@teteqami = teteqamis(:michael)
gba_ende(@teteqami)
end
test "የሚከተሉ ገጽ" do
get miketelachew_teteqami_path(@teteqami)
assert_not @teteqami.miketelachew.empty?
assert_match @teteqami.miketelachew.count.to_s, response.body
@teteqami.miketelachew.each do |teteqami|
assert_select "a[href=?]", teteqami_path(teteqami)
end
end
test "የተከታዮች ገጽ" do
get teketayoch_teteqami_path(@teteqami)
assert_not @teteqami.teketayoch.empty?
assert_match @teteqami.teketayoch.count.to_s, response.body
@teteqami.teketayoch.each do |teteqami|
assert_select "a[href=?]", teteqami_path(teteqami)
end
end
end
በዝርዝር 14.29 ውስጥ ይህንን ማረጋገጫ ማካተታችንን አስታውሱ:-
assert_not @teteqami.miketelachew.empty?
ይህም ይሄ:-
@teteqami.miketelachew.each do |teteqami|
assert_select "a[href=?]", teteqami_path(teteqami)
end
በትክክል እውነት ያልሆነ መሆኑን ለማረጋገጥ የተካተተ ነው (ለ‘ተከታዮች‘ም (teketayoch
) እንደዛው ነው)፡፡ በሌላ አማርኛ፣ @ተጠቃሚ.ሚከተላቸው.የለለነውን? (@teteqami.miketelachew.empty?
) እውነት ቢሆን፣ አንድም የ‘መለያ_አረጋግጥ (assert_select
) ማረጋገጫ በምልልሱ ውስጥ አይከናወንም ማለት ነው፤ ይህም ፈተናወቹ እንዲያልፉ እና በዚህም እኛን ከእውነት የራቀ የመተማመን ስሜት እንዲኖረን ያደርጋል፡፡
የፈተና ስብስቡ አሁን አረንጓዴመሆን አለበት:-
$ rails test
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
assert_select
) ማረጋገጫ የሚፈትነውን የአፕልኬሽኑ ኮድ ላይ አንድ አስተያየትን በማደረግ ፈተናውን ወደ ቀይ በመቀየር፣ ፈተናው ትክክለኛውን ነገር እየፈተነ መሆኑን አረጋግጡ፡፡
አሁን የመከተያ አዝራሮቹ እየሰሩ ነው፣ ስለዚህ ምልሰቶችን ለመከላከል፣ አንዳንድ ቀላል ፈተናወችን እንጽፋለን፡፡ አንድ ተጠቃሚን ለመከተል፣ ተጠቃሚውን በትስስሮች መንገድ ላይ ዕናስቀምጥ እና ከዚያ የተከተሉት ተጠቃሚዎች ቁጥር በ 1 እንደጨመረ እናረጋግጣለን:-
assert_difference '@teteqami.miketelachew.count', 1 do
post tssrs_path, params: { ktl_id: @lela.id }
end
ይህ መደበኛ ትግበራውን ይፈትናል፣ ይሁን እንጅ በኤጃክስ የተሰራውን ትግበራ መፈተኑ ከዚሁ ጋር ፍጹም ተመሳሳይ ነው፤ አንድ ብቸኛ ልዩነት ቢኖር፣ አንድ ተጨማሪ የ‘:ኤክስኤችአር እውነት (xhr: true
) አማራጪ መኖሩ ነው:-
assert_difference '@teteqami.miketelachew.count', 1 do
post tssrs_path, params: { ktl_id: @lela.id }, xhr: true
end
እዚህ ላይ፣ የ‘ኤክስኤችአር (xhr
) አማራጪን በ‘እውነት (true
) ማቀናበሩ፣ በፈተናው ውስጥ አንድ የኤጃክስ መጠይቅ እንዲያቀርብ ያደርጋል፣ ይህም በዝርዝር 14.36 ውስጥ ያለውን የ‘ምላሽ_ስጥ (respond_to
) ጥምርን ትክክለኛውን የጃቫስክሪፕት ዘዴን እንዲፈጽም ያደርገዋል (xhr
የኤክሰኤምሌል ሃ.ጽ.ማ.ስ መጠይቅ (XmlHttpRequest) ማለት ነው)፡፡14
የ‘አስቀምጥ (post
) ዘዴን ቦታ በ‘ሰርዝ (delete
) ዘዴ በመተካት፣ ተጠቃሚወችን ላለመከተል፣ ተመሳሳይ ትይዩ መዋቅርን ተግባር ላይ ማዋል ይቻላል፡፡ እዚህ ጋር፣ የተከታዮቹ ተጠቃሚዎች ብዛት በ 1 እንደቀነሰ፣ እና እንዲሁም ትስስሩ እና የክትሉ መታወቂያ እንደተካተተ እናረጋግጣለን:-
assert_difference '@teteqami.miketelachew.count', -1 do
delete tssr_path(tssr)
end
እንዲሁም በኤጃክስ እንደሚከተለው አድርገን እናረጋግጣለን:-
assert_difference '@teteqami.miketelachew.count', -1 do
delete tssr_path(tssr), xhr: true
end
ሁለቱን ሁኔታዎች በአንድ ላይ በማስቀመጥ፣ በዝርዝር 14.40 ውስጥ ያሉትን ፈተናወች እናገኛለን፡፡
test/integration/miketelachew_test.rb
require "test_helper"
class MiketelachewTest < ActionDispatch::IntegrationTest
def setup
@teteqami = teteqamis(:michael)
@lela = teteqamis(:ermias)
gba_ende(@teteqami)
end
.
.
.
test "አንድ ተጠቃሚን በመደበኛው መንገድ መከተል አለበት" do
assert_difference '@teteqami.miketelachew.count', 1 do
post tssrs_path, params: { ktl_id: @lela.id }
end
end
test "አንድ ተጠቃሚን በኤጃክስ መከተል አለበት" do
assert_difference '@teteqami.miketelachew.count', 1 do
post tssrs_path, xhr: true, params: { ktl_id: @lela.id }
end
end
test "አንድ ተጠቃሚን በመደበኛው መንገድ አለመከተል አለበት" do
@teteqami.teketel(@lela)
tssr = @teteqami.nq_tssrs.find_by(ktl_id: @lela.id)
assert_difference '@teteqami.miketelachew.count', -1 do
delete tssr_path(tssr)
end
end
test "አንድ ተጠቃሚን በኤጃክስ አለመከተል አለበት" do
@teteqami.teketel(@lela)
tssr = @teteqami.nq_tssrs.find_by(ktl_id: @lela.id)
assert_difference '@teteqami.miketelachew.count', -1 do
delete tssr_path(tssr), xhr: true
end
end
end
በዚህ ጊዜ ፈተናወቹ አረንጓዴመሆን አለባቸው:-
$ rails test
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
respond_to
) ጥምር ስር ያሉ ሁለት መስመሮች ላይ (ዝርዝር 14.36)፣ ማለት በእያንዳንዳቸው ላይ አስተያየት በማድረግ እና ባለማድረግ፣ ፈተናወቹ መፈተን የሚገባቸውን ነገር መፈተናቸውን አረጋግጡ፡፡ በያንዳዱ ሁኔታ ላይ የትኛው ፈተና ወደቀ?
xhr: true
ብታስወግዱት ምን ይሆናል? ይህ ምን አይነት ችግር እንደሚያስከትል አብራሩ? ከዚህ በፊት የነበረው መልመጃ ላይ ያለው አሰራር ለምን ችግሩን እንዳልያዘው አብራሩ?
አሁን የማሳያ አፕልኬሽናችን ጉልላት ወደሆነው፤ የአጪርጽሑፎች የሁኔታ ቀላቢው ላይ ደርሰናል። ይህ ክፍል በዚህ ስልጠና ውስጥ ካሉት ነገሮች ሁሉ በጣም ላቅ ያሉ አንዳንድ ነገሮችን በሚገባ ያካትታል። ሙሉው የሁኔታ ቀላቢው የሚገነባው፣ በክፍል 13.3.3 ቀደምት-ቀላቢ ላይ ነው፤ የሚገነባውም በአሁኑ ተጠቃሚ፣ አጪርጽሑፎች እና እሱ ከሚከተላቸው ተጠቃሚዎች አጪርጽሑፎች ጋር በተሰባሰበ አንድ ድርድር ይሆናል። በዚህ ክፍል ውስጥ፣ ከጊዜ ወደ ጊዜ ርቀቱ/ውስብስብነቱ እየጨመረ የሚሄደውን የሁኔታ ቀላቢ አተገባበር ሂደትን በማከታተል ጉዞዋችንን እንቀጥላለን። ይህንን ለማከናወን፣ በተወሰነ ደረጃ የላቀ የሬይልስ፣ የሩቢ እና እንዲሁም የተ.መ.ቋ ፕሮግራም ስልቶችን እንፈልጋለን፡፡
ከፊለፊታችን አንድ ከባድ ስራ ስለሚጠብቀን፣ ከወዲሁ ስራውን መገምገሙ በጣም ጠቃሚ ነገር ይሆናል፡፡ ስለሆነም፣ በምስል 14.5 ላይ ታይቶ የነበረው የመጨረሻው የሁኔታ ቀላቢ፣ አጠቃላይ መግለጫ አሁንም በድጋሚ በምስል 14.21 ላይ ቀርቧል፡፡
ከቀላቢው ጀርባ ያለው መሰረታዊ ሃሳብ ግልጽ ነው፡፡ ምስል 14.22 አንድ የ‘አጪርጽሑፎች (achrtshufs
) ናሙና ውሂበጎታ ሰንጠረዥን እና የተገኘውን የቀላቢ ውጤት ያሳያል፡፡ የአንድ ቀላቢ ዋና ዓላማው፣ ስእሉ ላይ ባሉ ቀስቶች እንደተመለከተው፣ የተጠቃሚዎቹ መታወቂያ፣ የአሁን ተጠቃሚ ከሚከተላቸው ተጠቃሚዎች ጋር የሚዛመዱ አጪርጽሑፎችን ጎትቶ ማውጣት ነው (የአሁን ተጠቃሚው አጪርጽሑፎችንም ይጨምራል)፡፡
ምንም እንኳን ቀላቢውን እንዴት መተግበር እንዳለበት ገና ባናውቅም፣ ፈተናወቹን መጻፉ ግን በአንጻሩ በጣም ቀላል ነው፤ ስለሆነም (በሳጥን 3.3 ውስጥ ያሉትን መመሪያዎች በመከተል) በመጀመሪያ ፈተናወቹን እንጽፋለን። ዋናው ነገር እነዚህን ሶስት የቀላቢ መስፈርቶችን ማረጋገጥ ነው፤ በቀላቢው ውስጥ የተከታይ እና የተከታዮች አጪርጽሑፎች መካተት ሲኖርባቸው፣ ከአንድ የማይከተሉት ተጠቃሚ የመጣ አንድ አጪርጽሑፍን ግን ማካተት የለበትም፡፡
በዝርዝር 14.28 ላይ እንደምናየው፣ ማይክል ገሬን እንጅ ኤርምያስን እንደማይከተል አድርገን እናዘጋጀዋለን፤ በዝርዝር 10.47 እና በዝርዝር 13.55 ውስጥ ባሉት እቃዎች መሰረት፣ ይህ ማለት፣ ማይክል የገሬን እና የራሱን አጪርጽሑፎች ማየት ሲኖርበት፣ የኤርምያስን አጪርጽሑፎች ግን ማየት የለበትም ማለት ነው፡፡ እንዲሁም ሁሉም ተጠቃሚዎች የራሳቸውን አጪርጽሑፎች (ከሁለቱም ከተከታዮቻቸው እና ከማይከተላቸው ጋር) ማየታቸውን ማረጋገጥ እንፈልጋለን፡፡ እነዚህን መስፈርቶች ወደ ማረጋገጫዎች መለወጥ እና ቀላቢ‘ው (qelabi
) በተጠቃሚ ቅርጸቱ (ዝርዝር 13.46) ውስጥ እንዳለ ማስታወሱ፣ በዝርዝር 14.42 ውስጥ የተመለከተውን የተሻሻለውን የተጠቃሚ ቅርጸት ፈተናን ይሰጣል፡፡
test/models/teteqami_test.rb
require 'test_helper'
class TeteqamiTest < ActiveSupport::TestCase
.
.
.
test "ቀላቢ ትክክለኛ ቅምጦች ሊኖሩት ይገባል" do
michael = teteqamis(:michael)
ermias = teteqamis(:ermias)
gerie = teteqamis(:gerie)
# ከተከተሉት ተጠቃሚ የተለጠፉ ቅምጦች
gerie.achrtshufs.each do |keteketelut_qmt|
assert michael.qelabi.include?(keteketelut_qmt)
end
# በራስ የተቀመጡ ቅምጦች ከተከታዮች ጋር
michael.achrtshufs.each do |yeras_qmt|
assert michael.qelabi.include?(yeras_qmt)
end
# ምንም ተከታዮች ከለለው ተጠቃሚ የተቀመጡ ቅምጦች
ermias.achrtshufs.each do |yeras_qmt|
assert ermias.qelabi.include?(yeras_qmt)
end
# ከማይከተሉት ተጠቃሚ የተቀመጡ ቅምጦች
ermias.achrtshufs.each do |kemiketelut_qmt|
assert_not michael.qelabi.include?(kemiketelut_qmt)
end
end
end
በእርግጥ፣ አሁን ያለው አተገባበር፣ አንድ ቀደምት-ቀላቢን መተግበር ብቻ ስለሆነ፣ አዲሱ ፈተና በመጀመሪያ ቀይሊሆን ይገባዋል:-
$ rails test
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
teteqami.qelabi.map(&:id)
ምንን ይመልሳል? ጠቃሚ ምክር:- ክፍል 13.1.4 ላይ የተማርነውን ነባሪ ክልሉን አስታውሱ፡፡
በዝርዝር 14.42 ፈተና ውስጥ ከተገኙት፣ የሁኔታ ቀላቢ ንድፍ መስፈርቶች ጋር፣ አሁን ቀላቢውን መጻፍ ለመጀመር ዝግጁ ነን። የመጨረሻው የቀላቢ አተገባበር በጣም የተወሳሰበ ስለሆነ፣ በአንድ ጊዜ አንድ ትንሽ ክፍልን በማስተዋወቅ፣ በትንሽ በትንሹ እንገነባዋለን። የመጀመሪያው ሂደት የምንፈልገው መጠይቅ ምን ዓይነት መሆኑን ማሰብ ነው፡፡ አንድ የተሰጠ ተጠቃሚ (ወይም ተጠቃሚው ራሱ) ከሚከተላቸው ተጠቃሚዎች መታወቂያዎች ጋር የሚዛመዱ አጪርጽሑፎችን (ማለት የሚከትላቸው ተጠቃሚወች የመታወቂያዎች ክምችትን) በሙሉ ከአጪርጽሑፎች (achrtshufs
) ሰንጠረዥ ውስጥ መምረጥ ይኖርብናል፡፡ ይህንን በንድፋዊ መልኩ እንደሚከተለው ልንጽፍ እንችላለን:-
SELECT * FROM achrtshufs
WHERE teteqami_id IN (<የመታወቂያ ዝርዝሮች>) OR teteqami_id = <teteqami id>
ይህንን ኮድ ስንጽፍ፣ ተ.መ.ቋ (SQL) የስብስብ መካተትን ለመሞከር የሚያስችለንን አንድ የውስጥ (IN
) ቁልፈቃልን እንደሚደግፍ ገምተን ነበር፡፡ ደስ ሲል! ያሰብነው ተሳክቷል፤ ማለት ይህንኑ ቁልፈቃል መጠቀም እንችላለን ማለት ነው፡፡
በዝርዝር 13.46 ላይ እንደተብራራው፣ በክፍል 13.3.3 ውስጥ በቀደምት-ቀላቢ ላይ፣ ንቅ መዝገብ ከላይ የተመለከተውን ዓይነት ምርጫ ለማከናወን፣ የ‘የት (where
) ዘዴን እንደሚጠቀም አስታውሱ፡፡ እዚያ ላይ ምርጫችን በጣም ቀላል ነበር፤ ያደረግነውም ከአሁን ተጠቃሚው መታወቂያ ጋር የሚዛመዱትን አጪርጽሑፎችን በሙሉ መርጦ ማውጣት ብቻ ነበር:-
Achrtshuf.where("teteqami_id = ?", id)
እዚህ ላይ ግን እንደበፊቱ ቀላል ሳይሆን በጣም የተወሳሰበ ምርጫን እንፈልጋለን፣ ማለትም ይህን የመሰለ:-
Achrtshuf.where("teteqami_id IN (?) OR teteqami_id = ?",
miketelachew_ids, id)
ከእነዚህ ሁኔታዎች በመነሳት፣ መታወቂያቸው ከሚከተሉት ተጠቃሚዎች ጋር የሚዛመድ፣ መታወቂያዎችን የያዘ አንድ ድርድር እንደሚያስፈልገን እንገነዘባለን። ይህንን ስራ ተግባራዊ ለማድረግ አንዱ መንገድ፣ የሩቢ ካርታ (map
) ዘዴን መጠቀም ነው፤ ይህም በሩቢ ፕሮግራም ውስጥ በማንኛውም “ተቆጣሪ (Enumerable)” ቁሶች ላይ ይገኛል፤ ማለትም፣ አንድ የአባላቶች ክምችት፣ ባካተተ ማንኛውም ቁስ (ማለት እንደ ድርድር ወይም ተርታ ባሉ) ላይ ይገኛል/ይሰራል ማለት ነው።15 በክፍል 4.3.2 ላይ የዚህን ዘዴ አሰራር ለመማር አንድ ምሳሌን ተመልክተን ነበር፤ እንደ አንድ ተጨማሪ ምሳሌ ይሆናችሁ ዘንድ፣ አንድ የቁጥሮች ድርድርን ወደ አንድ ሃረጎች ድርድር ለመቀየር የ‘ካርታ (map
) ዘዴን እንጠቀማለን:-
$ rails console
>> [1, 2, 3, 4].map { |i| i.to_s }
=> ["1", "2", "3", "4"]
ከላይ እንደተብራራው አይነት ምሳሌ ሁኔታ ላይ፣ በአንድ ክምችት ውስጥ በእያንዳንዱ አባል ላይ አንድ ዓይነት ዘዴን መጥራት የተለመደ አሰራር ስለሆነ፣ ለዛም አንድ አጪር የአጻጻፍ ስርዓተ-ምልክት አለው (በክፍል 4.3.2 ላይ በግልጽ ታይቷል)፤ ያም አንድ እናን (&
) እና ከዘዴው ጋር የሚዛመድ አንድ ወካይን ይጠቀማል:-
>> [1, 2, 3, 4].map(&:to_s)
=> ["1", "2", "3", "4"]
የ‘አገጣጥም (join
) ዘዴን በመጠቀም (ክፍል 4.3.1)፣ በነጠላሰረዝ-ክፍትቦታ በተገጣጠሙ መታወቂያዎች የተዋቀረ አንድ ሃረግን መፍጠር እንችላለን:-
>> [1, 2, 3, 4].map(&:to_s).join(', ')
=> "1, 2, 3, 4"
በ‘ተጠቃሚ.ሚከተላቸው (teteqami.miketelachew
) ስብስብ ውስጥ፣ በእያንዳንዱ አባል ላይ መታወቂያ‘ን ( id
) በመጥራት አስፈላጊውን የተጠቃሚ ተከታዮች ድርድርን ለመገንባት፣ ከላይ የተጠቀሰውን ዘዴ መጠቀም እንችላለን፡፡ ለምሳሌ፣ በውሂበጎታው ውስጥ ላለው የመጀመሪያው ተጠቃሚ፣ የተከታዮች የመታወቂያዎች ድርድር እንደሚከተለው ሁኖ ይታያል ማለት ነው:-
>> Teteqami.first.miketelachew.map(&:id)
=> [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
42, 43, 44, 45, 46, 47, 48, 49, 50, 51]
በእርግጥ፣ የዚህ ዓይነቱ ግንባታ በጣም ጠቃሚ በመሆኑ የተነሳ፣ ንቅ መዝገብ ይህን አሰራር በነባሪነት ያቀርባል:-
>> Teteqami.first.miketelachew_ids
=> [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
42, 43, 44, 45, 46, 47, 48, 49, 50, 51]
እዚህ ላይ የ‘ሚከተላቸው_መታወቂያዎች (miketelachew_ids
) ዘዴ በ‘ብዙ_ሚከተላቸው አሉት (has_many :miketelachew
) ማሕበር መሰረት በ‘ንቅ መዝገብ የተቀናጀ ነው (ዝርዝር 14.8)፤ ስለዚህ ከ‘ተጠቃሚ.ሚከተላቸው (teteqami.miketelachew
) ክምችት ጋር የሚዛመዱ መታወቂያዎችን ለማግኘት፣ የማሕበሩ ስም ላይ _መታወቂያዎች ‘ን (_ids
) ብቻ ማያያዝ ይኖርብናል ማለት ነው። ከዚያ የአንድ የተከታይ ተጠቃሚ መታወቂያዎች ሃረግ እንደሚከተለው ሁኖ ይታያል:-
>> Teteqami.first.miketelachew_ids.join(', ')
=> "3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
42, 43, 44, 45, 46, 47, 48, 49, 50, 51"
አንድ የተ.መ.ቋ ሃረግን በመጠይቅ ውስጥ በምታስገቡበት ጊዜ፣ የሃረግ ውስጠገምትን መጠቀም አያስፈልጋችሁም፤ የ ?
ውስጠገምት በናንተ ስም እሱን ያደርግላችኋል (እናም በእውነቱ፣ አንዳንድ በውሂበጎታ ላይ ጥገኛ የሆኑ ነገሮች ላይ የሚከሰቱ አለመጣጣሞችንም ያስወግዳል)፡፡ ይህ ማለት ሚከተላቸው_መታወቂያዎች‘ን (miketelachew_ids
) ራሱን መጠቀም እንችላለን ማለት ነው። በዚህ ምክንያትም ይህ:-
Achrtshuf.where("teteqami_id IN (?) OR teteqami_id = ?",
miketelachew_ids, id)
የመጀመሪያው ግምት ይሆናል፣ የመጀመሪያው ግምታችንም በትክክል ይሰራል! ውጤቱም በዝርዝር 14.44 ውስጥ ይታያል።
app/models/teteqami.rb
class Teteqami < ApplicationRecord
.
.
.
# አንድ የመሕለፈቃል ዳግምማስጀመሪያ ጊዜው ካበቃ እውነትን ይመለሳል።
def mehlefeqal_damasjemerya_abqtualn?
masjemer_tesedede_at < 2.hours.ago
end
# የአንድ ተጠቃሚ ሁኔታ ቀላቢን ይመልሳል።
def qelabi
Achrtshuf.where("teteqami_id IN (?) OR teteqami_id = ?",
miketelachew_ids, id)
end
# አንድ ተጠቃሚን ይከተላል።
def teketel(lela_teteqami)
miketelachew << lela_teteqami unless self == lela_teteqami
end
.
.
.
end
የፈተና ስብስቡ አረንጓዴመሆን አለበት:-
$ rails test
በአንዳንድ አፕልኬሽኖች ላይ፣ ይህ የመጀመሪያ አተገባበር ለአብዛኞቹ ተግባራዊ ዓላማዎች በቂ ሊሆን ይችላል፣ ይሁን እንጂ፣ ዝርዝር 14.44 የመጨረሻው አተገባበር አይደለም፤ ወደ ቀጣዩ ክፍል ከመቀጠላችሁ በፊት፣ ለምን እምብዛ በቂ እንዳልሆነ መገመት ትችላላችሁን? (ጠቃሚ ምክር:- አንድ ተጠቃሚ 5000 ተጠቃሚዎችን የሚከተል ከሆነ ውሂበጎታው ላይ ምን ይፈጥራል?)
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
በመጨረሻው ክፍል ላይ በተሰጠው ፍንጪ እና ብዙውን ጊዜ እንደሚያጋጥመው፣ ለምሳሌ እንበል አንድ ተጠቃሚ 5000 ተጠቃሚዎችን ቢከተል እናም ይህንን ተጠቃሚ ለማስተናገድ ብንሞክር፣ በክፍል 14.3.2 ውስጥ ያለው የቀላቢ አተገባበር፣ ለቀላቢው ቁጥር ስፍር የሌለው አጪርጽሑፎችን ስለሚጠይቅ በደንብ አይመዝንም (Scale) (መመዘን (Scale) ማለት ቅልጣፌ ማለት ነው)፡፡ በዚህ ክፍል ውስጥ የሁኔታ ቀላቢውን፣ ከተከታይ ተጠቃሚዎች ብዛት ጋር በተሻለ መልኩ እንዲመዝን አድርገን እንዳዲስ እንተገብረዋለን፡፡
በክፍል 14.3.2 ውስጥ ያለው ኮድ የመጀመሪያ ችግሩ፣ የ‘ሚከተላቸው_መታወቂያወች (miketelachew_ids
) ሁሉንም የተከታይ ተጠቃሚዎች መታወቂያዎችን በማህደረ-ትውስታው ላይ ጎትቶ የሚጪን መሆኑ ነው፣ ይህም ሁሉንም ተከታይ ተጠቃሚዎች የያዘ አንድ ድርድርን ይፈጥራል። በዝርዝር 14.44 ውስጥ ያለው ሁኔታ የሚያረጋግጠው፣ የተፈለገው ነገር በአንድ ስብስብ ውስጥ መካተቱን ነው፣ በእውነቱ ይህን ለማድረግ፣ ከዚያ የተሻለ አንድ ቀልጣፋ መንገድ መኖር አለበት፣ እናም በእርግጥ ተ.መ.ቋ ለእንዲዚህ ዓይነቶቹ የስብስብ ተግባሮች የተባ ነው። መፍትሄውም አንድ ንዑስምርጫ የተባለ አሰራርን በመጠቀም የተከታይ ተጠቃሚዎች መታወቂያዎችን የመፈለግ ስራውን ወደ ውሂበጎታው ማሸጋገርን ያሳትፋል፡፡
በዝርዝር 14.46 ውስጥ በጥቂቱ በተሻሻለው ኮድ፣ ቀላቢውን በማጣራት እንጀምራለን።
where
) ዘዴ ውስጥ የቁልፍ እና የዋጋ ጥንዶችን መጠቀም፡፡ አረንጓዴ app/models/teteqami.rb
class Teteqami < ApplicationRecord
.
.
.
# የአንድ ተጠቃሚ ሁኔታ ቀላቢን ይመልሳል።
def qelabi
Achrtshuf.where("teteqami_id IN (:miketelachew_ids) OR
teteqami_id = :teteqami_id", miketelachew_ids:
miketelachew_ids, teteqami_id: id)
end
.
.
.
end
ወደ ሚቀጥለው ደረጃ ለማለፍ ይህንን፡-
Achrtshuf.where("teteqami_id IN (?) OR teteqami_id = ?",
miketelachew_ids, id)
በዚህ ቀይረናል:-
Achrtshuf.where("teteqami_id IN (:miketelachew_ids) OR
teteqami_id = :teteqami_id", miketelachew_ids:
miketelachew_ids, teteqami_id: id)
የጥያቄ ምልክቱ አገባብ በጣም ጥሩ ነው፣ ነገር ግን አንድ ተለዋዋጪን ከአንድ ወይም ከዚያ በላይ በሆነ ቦታ ላይ ማስገባት ከፈለግን፣ ሁለተኛው አገባብ የበለጠ አመች ይሆናል፡፡
ከዚህ በላይ ያለው ውይይት የሚያሳየው በተ.መ.ቋ መጠይቁ ላይ አንድ ሁለተኛ የ‘ተጠቃሚ_መታወቂያ (teteqami_id
) ተለዋዋጪን ማከል እንዳለብን ነው፡፡ እኛም እዚህ ላይ የሩቢ ኮዱን:-
miketelachew_nous_mrcha
በዚህኛው የተ.መ.ቋ ቁርጥራጪ (snippet)16 መተካት እንችላለን:-
miketelachew_nous_mrcha = "SELECT ktl_id FROM tssrs
WHERE teketay_id = :teteqami_id"
ይህ ኮድ የተ.መ.ቋ ንዑስክፍልን የያዘ ነው፣ እናም ለ ( 1) ቁጥር ተጠቃሚ ሁሉንም ክትሎች ከውሂበጎታው ለመሰብሰብ የምንጠቀምበት ኮድ ይህንን ይመስላል:-
SELECT * FROM achrtshufs
WHERE teteqami_id IN (SELECT ktl_id FROM tssrs
WHERE teketay_id = 1)
OR teteqami_id = 1
ይህ ንዑስክፍል ሁሉንም ጫና ወደ ውሂበጎታው ይልካል፡ ይህም ስራውን በጣም ቀልጣፋ ያደርገዋል።
ከዚህ በላይ ካገኘነው መሰረት ጋር፣ አንድ ይበልጥ ቀልጣፋ የሆነ፡ የቀላቢ ትግበራን ለመስራት ዝግጁ ነን፡፡ በዝርዝር 14.47 ላይ እንደሚታየው፣ አሁን እዚህ ላይ የምንጠቀመው ጥሬ ተ.መ.ቋን ስለሆነ፣ የ‘ሚከተላቸው_ንዑስ_ምርጫ (miketelachew_nous_mrcha
) ሃረጉ ከመዘለል ይልቅ ውስጠገምት መደረጉን ልታስተውሉ ይገባል፡፡
app/models/teteqami.rb
class Teteqami < ApplicationRecord
.
.
.
# የአንድ ተጠቃሚ ሁኔታ ቀላቢን ይመልሳል።
def qelabi
miketelachew_nous_mrcha = "SELECT ktl_id FROM tssrs
WHERE teketay_id = :teteqami_id"
Achrtshuf.where("teteqami_id IN (#{miketelachew_nous_mrcha})
OR teteqami_id = :teteqami_id", teteqami_id: id)
end
.
.
.
end
እንደተለመደው፣ የፈተና ስብስቡን በማስኬድ፣ ኮዱ እንደሚሰራ ማረጋገጥ እንችላለን:-
$ rails test
ሁለተኛው ችግር፣ በዝርዝር 14.47 ውስጥ ይበልጥ ቀልጣፋ የሆነው ኮድ እንኳን፣ ተዛማጅ ተጠቃሚዎችን (ወይም አባሪዎችን) ሳይጨምር፣ የቀላቢውን አጪርጽሑፎች ብቻ መጎተቱ ነው፡፡ በዚህ ምክንያትም አጪርጽሑፍ ከፊልን (ዝርዝር 13.72) የሚጠራው የቀላቢው ከፊል (ዝርዝር 13.51)፣ ከእያንዳንዱ አጪርጽሑፍ ጋር የሚዛመደውን ተጠቃሚ ለመፈለግ፣ አንድ ተጨማሪ የውሂበጎታ ምትን ያመነጫል፡፡ \( ሀ \) ‘ን ያህል ብዛት ያላቸው አጪርጽሑፎች ካሉ፣ ዝርዝር 14.47 አጪርጽሑፎቹን ለመጎተት \( 1 \) መጠይቅን ብቻ እንደሚጠቀም ሳይታለም የተፈታ ሃቅ ነው፤ ነገር ግን የቀላቢ ትይታው ራሱ፣ እያንዳንዱን የአጪርጽሑፍ ተጠቃሚ ለመፈለግ፣ ተጨማሪ \( ሀ \) መጠይቆችን ያመነጫል፣ ማለት በድምሩ \( ሀ+1 \) መጠይቆችን ያመነጫል ማለት ነው። (\( ሀ \) ‘ን ያህል ለተያያዙ ምስሎችም፣ ያንኑ ያህል ነጋሪአሴትን ይተገብራል፤ ስለሆነም በዚህ ሁኔታ፣ የመጠይቆቹ ብዛት ከ \( 2ሀ+1 \) በላይ ሊበልጥ ይችል ይሆናል።) የ \( ሀ+1 \) መጠይቅ ችግር ተብየው፣ የውሂበጎታው መጠን እያደገ ሲሄድ፣ የአንድ አፕልኬሽን አፈጻጸምን ቀስ በቀስ ወደታች ሊያወርድ ይችላል።
የዚህ ችግር መፍትሄ፣ አንድ በጉጉት ጫኝ (Eager Loading) ተብሎ የሚታወቅ ዘዴን ማሳተፍን ይጠይቃል፡፡ በኬቪን ጊልፒን፣ በለርን ኢነፍ ብሎግ አጪርጽሑፍ “በጉጉት ጫኝ እና የ \( ሀ+1 \) መጠይቅ ችግር” ላይ በበለጠ በዝርዝር እንደተብራራው፣ በጉጉት ጫኝ፣ ተጠቃሚዎችን (እና ምስሎችን) ልክ እንደ አንድ ነጠላ የአጪርጽሑፍ መጠይቅ አካል አድርጎ ያካትታቸዋል፣ ስለሆነም ለቀላቢው የሚያስፈልጉ ነገሮች ሁሉ፣ በአንድ ጊዜ ይጎትታል፣ በዚህም ውሂበጎታውን አንድ ጊዜ ብቻ እንዲመታ ያደርጋል፡፡ ከዚህ ስልት የሚገኘው ቅልጣፌም ከፍተኛ ሊሆን ይችላል፡፡
በሬይልስ ውስጥ በጉጉት ጫኝን የመጠቀም መንገዱ፣ አንድ አክል (includes
) በተባለ ዘዴ በኩል ነው፡፡ አሁን ባለው ሁኔታ ላይ፣ አክልን (includes
) ከ‘አጪርጽሑፍ.የት (Achrtshuf.where
) ጋር በማስተሳሰር ሁለቱንም ማለት የአጪርጽሑፍ ተጠቃሚውን እና የምስል አባሪውን (ካለ) ማካተት እንችላለን:-
Achrtshuf.where("teteqami_id IN (#{miketelachew_nous_mrcha})
OR teteqami_id = :teteqami_id", teteqami_id: id)
.includes(:teteqami, msl_attachment: :blob)
ይህንን ኮድ በዝርዝር 14.47 ላይ ማከሉ፣ በዝርዝር 14.49 ውስጥ የሚታየውን ቀላቢ (qelabi
) ያስገኛል፡፡
app/models/teteqami.rb
class Teteqami < ApplicationRecord
.
.
.
# የአንድ ተጠቃሚ ሁኔታ ቀላቢን ይመልሳል።
def qelabi
miketelachew_nous_mrcha = "SELECT ktl_id FROM tssrs
WHERE teketay_id = :teteqami_id"
Achrtshuf.where("teteqami_id IN (#{miketelachew_nous_mrcha})
OR teteqami_id = :teteqami_id", teteqami_id: id)
.includes(:teteqami, msl_attachment: :blob)
end
.
.
.
end
አንድ የመጨረሻ የፈተና ስብስብ ማስኬዱ፣ በዝርዝር 14.49 ውስጥ ያለው ቀላቢ እንደተፈለገው እንደሚሰራ ያረጋግጣል:-
$ rails test
በአፕልኬሽናችን ውስጥ ማንኛውንም ምልሰት መያዝ እንድንችል፣ በጉጉት ጫኝን በቀጥታ መፈተኑም ጥሩ በሆነ ነበረ። ይህን ማድረጉም አንዳንድ የላቁ የፈተና ስልቶችን ይጠይቃል፣ እንደዛ ይሁን እንጅ በእርግጠኝነት መፈተንም ይቻላል፤ እንዴት እሱን መፈተን እንደሚቻል አንዳንድ ዝርዝሮችን ለመመልከት “በጉጉት ጫኝ እና የ \( ሀ+1 \) መጠይቅ ችግር” ላይ ተመልከቱ።
በእርግጥ፣ ንዑስምርጫው እና በጉጉት ጫኙ ለዘልዓለም የሚመዝኑ (የሚቀለጥፋ) አይደሉም፡፡ አንድ በጣም ብዙ ተጠቃሚዎችን ሊያስተናግድ የሚችል ጣቢያን ለመገንባት የምትፈልጉ ከሆነ፣ ቀላቢውን ባልተመሳሰለ መልኩ (Asynchronously) ለማመንጨት (ማለት በአንድ ጊዜ ከአንድ በላይ የሆነ ቀላቢን ለማመንጨት) የመሳሰሉትን ነገሮች ለማድረግ አንድ የዳራ ስራ ( Background Job) የተባለ አሰራርን መጠቀም ይኖርባችኋል። እንደዚህ ዓይነቶቹን ረቂቅ የሚዛን (የመቀልጠፍ) ሳንካዎች፣ ተግባራዊ የማድረጉ ጉዳይ፣ ሙሉ በሙሉ ከዚህ ስልጠና ወሰን ውጪ ነው፤ ነገር ግን እናንተ ካዳበራችሁት ሙያዊ ክህሎት ጋር፣ የሚቀጥለውን እርምጃ ለመውሰድ በጣም ጥሩ የሆነ አቋም ላይ ናችሁ።
ዝርዝር 14.49 ላይ ካለው ኮድ ጋር፣ የሁኔታ ቀላቢያችን አሁን ተጠናቋል፡፡ (ይህንን ለማሻሻል የተደረገውን አንድ ጪማሬ ለማየት በክፍል 14.3.3.1 ውስጥ ያሉትን መልመጃዎች ተመልከቱ፡፡) ክፍል 13.3.3 ላይ የመነሻ ገጹ፣ ቀድሞውኑ ቀላቢውን ያካተተ እንደነበር አስታውሱ። በምዕራፍ 13 ላይ ውጤቱ አንድ ቀደምት-ቀላቢ (አጪርጽሑፎችን በዝርዝር ማሳየት) ብቻ ነበር (ምስል 13.14)፣ በምስል 14.23 ላይ እንደሚታየው፣ ግን በዝርዝር 14.49 ትግበራ ምክንያት የመነሻ ገጹ አሁን የተሟላውን ቀላቢ ያሳያል፡፡
በዚህ ጊዜ ለውጦቻችንን ወደ ዋናው ቅርንጫፍ ለማዋሃድ ዝግጁ ነን:-
$ rails test
$ git add -A
$ git commit -m "የተጠቃሚ መከተያን ማከል"
$ git checkout main
$ git merge ተጠቃሚዎችን-መከተል
ከዚያም ኮዱን ወደ ሩቁ ማከማቻ በመግፋት አፕልኬሽኑን ወደ ምርት ማሰማራት እንችላለን:-
$ git push
$ git push heroku
$ heroku pg:reset DATABASE
$ heroku run rails db:migrate
$ heroku run rails db:seed
የተገኘው ውጤት፣ በቀጥታ ድር ላይ የሚሰራ አንድ የሁኔታ ቀላቢ ነው (ምስል 14.24)፡፡ (አንድ ብጁ ግዝአትን በመጠቀም፣ ጣቢያችሁን በሃረኩ ድር ላይ እንዴት ማስተናገድ እንደምትችሉ ለማወቅ፣ ማለት ስለዚህ ጉዳይ የነጻ ትምህርት ለማግኘት፣ በብጁ ግዝአት ላይ መሰረታዊ እውቀትን ለማግኘት የሚያስፈልገውን ተማርን ጎብኙ፡፡)
የሬይልስ ስልጠናን ለገዙ ሰወች በሙሉ የሁሉም የመልመጃ መልሶች እዚህ ላይ ይገኛሉ።
የሌሎች ሰዎች መልሶችን ለማየት እና የራሳችሁን ደግሞ ለመመዝገብ፣ በሬይልስ ስልጠና ወይም ሁሉንም በበቂ ተማር መድረሻ ጥቅል ላይ ተመዝገቡ፡፡
ይህን_ሙሉ
በሚለው ምትክ፣ የራሳችሁን ኮድ ማስገባት ይጠበቅባችኋል፡፡
CGI.escapeHTML
) ዘዴን በመጠቀም፣ ከተጠበቀው ሃ.ጽ.መ.ቋ እንዳመለጠ ልብ ልትሉ ይገባል(
ይህም በክፍል 11.2.3 ውስጥ ዓ.አ.ሃ.አዎችን ለማስመለጥ ከተጠቀምንበት ከ‘ሲጅሲ.አምልጥ (CGI.escape
) ዘዴ ጋር በጣም የተዛመደ ነው።) እዚህ ላይ ሃ.ጽ.መ.ቋውን ማስመለጥ ለምን አስፈለገ? ጠቃሚ ምክር:- ማስመለጫውን ከፈተናው አስወግዱ እና ከዚያ የማይዛመደውን የአጪርጽሑፍ ይዘት በገጹ ምንጪ ላይ በጥንቃቄ ለመመርመር ሞክሩ፡፡ የመናኸሪያ ቀፎ ላይ ቃላትን የመፈለጊያ ገጸባህሪን ማለት “ተቆር-ኤፍን (Ctrl-F)” ወይም “ትእዝ-ኤፍን (Cmd-F)” በመጠቀም፣ “sorry” የሚለውን ቃል መፈለጉ በጣም ጠቃሚ ሊሆን ይችላል።
left_outer_joins
) ዘዴን በመጠቀም፣ ይህንን በሬይልስ ውስጥ በቀጥታ መግለጽ ይችላል፡፡ ፈተናዎቹን በማስኬድ፣ በዝርዝር 14.52 ውስጥ ያለው ኮድ፣ አንድ የሚያልፍ ቀላቢን እንደሚመልስ አረጋግጡ።17 አለመታደል ሆኖ፣ እውነተኛው ቀላቢ፣ የተጠቃሚውን ማለት የራሱ የሆኑ የተባዙ የአጪርጽሑፎች ቅጂዎችን ይይዛል (ምስል 14.25)፤18 ስለሆነም ይህንን ስህተት ለመያዝ፣ (በአንድ ክምችት ውስጥ፣ የተለዩ አባላቶችን የሚመልሰውን የ‘የተለየ (distinct
) ዘዴን ለመጠቀም) በዝርዝር 14.53 ውስጥ የሚገኘውን ፈተና ተጠቀሙ። ከዚያ የ‘የተለየ (distinct
) ዘዴን (ዝርዝር 14.54) በመጠይቁ ላይ መጨመሩ፣ አንድ አረንጓዴ ፈተናን እንደሚያስገኝ አሳዩ፡፡ በዚህ የመነጨውን ተ.መ.ቋ በቀጥታ በመመርመር፣ የተለየ (DISTINCT
) የሚለው ቃል፣ በራሱ ማለት በመጠይቁ ውስጥ መገኘቱን አረጋግጡ፤ ይህም የተለዩት አባላቶች፣ ከአፕልኬሽናችን ማህደረ-ትውስታ ላይ ከመመረጣቸው ይልቅ፣ በውሂበጎታው ውስጥ ብቃታዊ በሆነ መንገድ የተመረጡ መሆናቸውን ያመለክታል። (ጠቃሚ ምክር:- ተ.መ.ቋውን ለማግኘት ተጠቃሚ.አንደኛ.ቀላቢ‘ን (Teteqami.first.qelabi
) በሬይልስ ሰሌዳ ውስጥ አስኪዱ።)
test/integration/miketelachew_test.rb
require "test_helper"
class MiketelachewTest < ActionDispatch::IntegrationTest
def setup
@teteqami = teteqamis(:michael)
@lela = teteqamis(:ermias)
gba_ende(@teteqami)
end
.
.
.
test "የቀላቢው የመጀመሪያ ገጽ በመነሻ ገጹ ላይ መታየት አለበት" do
get root_path
@teteqami.qelabi.paginate(page: 1).each do |achrtshuf|
assert_match CGI.escapeHTML(ይህን_ሙሉ), ይህን_ሙሉ
end
end
end
join
) ዘዴን መጠቀም፡፡ app/models/teteqami.rb
class Teteqami < ApplicationRecord
.
.
.
# የአንድ ተጠቃሚ ሁኔታ ቀላቢን ይመልሳል።
def qelabi
yeqelabi_kfl = "tssrs.teketay_id = :id or achrtshufs.teteqami_id = :id"
Achrtshuf.left_outer_joins(teteqami: :teketayoch)
.where(yeqelabi_kfl, { id: id })
.includes(:teteqami, msl_attachment: :blob)
end
.
.
.
end
app/tests/teteqami_test.rb
require 'test_helper'
class TeteqamiTest < ActiveSupport::TestCase
.
.
.
test "ቀላቢ ትክክለኛ ቅምጦች ሊኖሩት ይገባል" do
michael = teteqamis(:michael)
ermias = teteqamis(:ermias)
gerie = teteqamis(:gerie)
# ከተከተሉት ተጠቃሚ የተቀመጡ ቅምጦች
gerie.achrtshufs.each do |keteketelut_qmt|
assert michael.qelabi.include?(keteketelut_qmt)
end
# በራስ የተቀመጡ ቅምጦች ከተከታዮች ጋር
michael.achrtshufs.each do |yeras_qmt|
assert michael.qelabi.include?(yeras_qmt)
assert_equal michael.qelabi.distinct, michael.qelabi
end
# ምንም ተከታዮች ከለለው ተጠቃሚ የተቀመጡ ቅምጦች
ermias.achrtshufs.each do |yeras_qmt|
assert ermias.qelabi.include?(yeras_qmt)
end
# ከማይከተሉት ተጠቃሚ የተቀመጡ ቅምጦች
ermias.achrtshufs.each do |kemiketelut_qmt|
assert_not michael.qelabi.include?(kemiketelut_qmt)
end
end
end
app/models/teteqami.rb
class Teteqami < ApplicationRecord
.
.
.
# የአንድ ተጠቃሚ ሁኔታ ቀላቢን ይመልሳል።
def qelabi
yeqelabi_kfl = "tssrs.teketay_id = :id or achrtshufs.teteqami_id = :id"
Achrtshuf.left_outer_joins(teteqami: :teketayoch)
.where(yeqelabi_kfl, { id: id }).distinct
.includes(:teteqami, msl_attachment: :blob)
end
.
.
.
end
የሁኔታ ቀላቢውን በማከል፣ የሩቢ ኦን ሬይልስ ስልጠና የማሳያ አፕልኬሽንን እዚህ ላይ አጠናቀናል፡፡ ይህ አፕልኬሽን ሁሉንም የሬይልስ መሰረታዊ ባህርያት ማለት የቅርጸቶች፣ የትይታዎች፣ የመቆጣጠሪያዎች፣ የዝግጁገጽታዎች፣ የከፊሎች፣ የማጣሪያወች፣ የማረጋገጫወች፣ የመልሰጥሪዎች፣ የ‘ብዙ_አለው (has_many
) / ባለቤት_ነው (belongs_to
) እና የ‘ብዙ_አለው በኩል (has_many :through
) ማሕበሮች፣ የጥበቃ፣ የመፈተን እና የማሰማራት ምሳሌዎችን ያካተቱ ባህርያት አሉበት፡፡
ከእነዚህ አስደናቂ ዝርዝሮች ባሻገር፣ አሁንም ስለ ድር ብልጸጋ ብዙ መማር የሚያስፈልጉ ነገሮች አሉ፡፡ በዚህ ሂደት ውስጥ ልክ እንደ አንድ የመጀመሪያ እርምጃ ይቆጠር ዘንድ፣ ይህ ክፍል በዚሁ አምድ ላይ ተጨማሪ ትምህርትን ለመማር የሚያግዙ በርካታ መንገዶችን ይጠቁማል፡፡
በመጽሐፍት ቤቶች እና በድር ላይ፣ ብዙ የሬይልስ መማሪያ ምንጮች አሉ፤ በእርግጥ፣ እጅግ ከመብዛታቸው የተነሳ ለመምረጥ ግራ ያጋባሉ። መልካሙ ዜና ግን፣ እናንተ ይህንን ያህል ከተማራችሁ በኋላ፣ እዛ ለምታገኙዋቸው ነገሮች ሁሉ፣ እናንተ ቀድሞውኑ ብቁ መሆናችሁ ነው፡፡ ከዚህ ቀጥሎ አንዳንድ ተጨማሪ ትምህርትን ለመማር የሚያግዙ ጥቆማዎችን ጀባ እላችኋለሁ:-
has_many :through
) የተወሳሰቡ የውሂብ ትስስሮችን መቅረጽን እንደሚፈቅድ፣
has_many
) ዘዴ የቁሱን የክፍል ስም እና የውጪ ቁልፉን ጨምሮ፣ በርካታ የነጋሪአሴት አማራጮችን እንደሚወስድ፣
has_many
) እና ብዙ_አለው በኩል‘ን (has_many :through
) በመጠቀም፣ የንቅ (የሚከተላቸው) እና የያልተካፈለ (የተከታዮች) ትስስሮችን መቅረጽ እንደምንችል፣
where
) ዘዴ የውሂበጎታ መጠይቆችን ለመፍጠር እንደልብ የሚገራ እና ሃይለኛ መንገድ መሆኑን፣
includes
) ዘዴን በመጠቀም፣ የ \( ሀ+1 \) መጠይቅ ችግርን መፍታት እንደምንችል እና
classify
) የተባለውን ዘዴ በመጠቀም፣ የ‘ብዙ_አለው (has_many
) ነጋሪአሴትን ወደ አንድ የክፍል ስም ይቀይረዋል፤ ይህ ማለት "tedi_mihretn"
‘ን ወደ "TediMihret"
ይቀይረዋል ማለት ነው፡፡id
) ለመቀየር የታች-ሰረዝ (underscore
) ዘዴን ይጠቀማል፤ ለምሳሌ የዚህ:- "MentaKeremela".underscore
መታወቂያ (id
) ይሄ:- menta_keremela_id
ነው። ስለዚህ የ MentaKeremela
ቁስ፣ የውጪ ቁልፍ menta_keremela_id
ይሆናል ማለት ነው፡፡each
) ዘዴን መተግበር ይኖርባቸዋል፡፡