Bygg Instagram av Ruby on Rails (del 3)
Visa-ta bort inlägg och skapa hashtaggar för inlägg och sök inlägg
Tidigare inlägg:
- Del 1: medium.com/luanotes/build-instagram-by-ruby-on-rails-part-1
- Del 2: medium.com/luanotes/build-instagram-by-ruby-on-rails-part-2
- Fullständig kod på Github: https://github.com/thanhluanuit/instuigram
Innehållsförteckning:
- Lägg till visa Post sida: Visa detaljerad information om Post.
- Lägg till radera postfunktion.
- Skapa Hashtags för inlägg.
- Implementera Search Posts-funktionen.
Vad lär du dig efter att ha läst artikeln?
- CRUD i aktiv post: Läs / radera inlägg och CRUD Hashtags
- Association in Active Record: The has_many: through association
- Aktiv postfråga: Hämta data från databasen med Active Record
Visa inläggdetaljer
Steg 1: Lägg till show action i Posts controller
klass PostsControllerI den här åtgärden släpps en postvariabel med params-id.
Steg 2: Lägg till show Visa: (app / visningar / inlägg / show.html.erb)
Sidans layout: till vänster på sidan visar inläggsbilden och till höger på sidan visar användarinformation och inläggsbeskrivning.
Full HTML-kod:
<% = image_tag @ post.image, class: 'image'%> <% om @ post.user.avatar.attached? %> <% = link_to user_path (@ post.user) do%> <% = image_tag @ post.user.avatar%> <% end%> <% end%> <% = link_to @ post.user.username, user_path (@ post.user), klass: 'användarnamn'%> <% = @ post.beskrivning%>CSS-kod: (app / tillgångar / stilark / posts.scss)
.post-show {marginal: 30px 5px 0; gräns: 1px solid #dbdbdb;.col-md-8 {polstring: 0; .bild {bredd: 100%; }}.användare {display: flex; stoppning: 10px 0; border-bottom: 1px solid #efefef;.avatar {bredd: 40px; höjd: 40px; marginal: 8px; img {bredd: 100%; höjd: 100%; kant: 1px solid #efefef; gränsradie: 50%; }} .namn {padding-top: 15px; färg: # 262626; teckenstorlek: 14px; font-vikt: 600; &: sväva {textdekoration: ingen; }}}.beskrivning {polstring: 15px 0; }}Steg 3: Lägg till rutter: (config / routes.rb)
resurser: inlägg, bara: [: nytt,: skapa,: visa]Uppdatering på sidan Användarprofil:
<% @ posts.each do | post |%> <% = link_to post_path (post) do%> <% = image_tag post.image%> <% end%> <% slut%>Radera ett inlägg
Vi lägger till en funktion som hjälper användaren att ta bort sina inlägg.
Steg 1: Lägg till förstöra åtgärder i Posts controller
def förstöra @post = current_user.posts.find (params [: id]) @ post.destroyomdirigera_till user_path (current_user) slutVi hittar ett inlägg via inlägg från aktuell användare för att undvika att någon ändrar parametrar [: id] i HTML och säkrare.
@post = current_user.posts.find (params [: id])Steg 2: Lägg till rutter: (config / routes.rb)
resurser: inlägg, bara: [: nytt,: skapa,: visa,: förstöra]Se nya rutter tillagda:
rake rutter | grep postMetoden för att förstöra åtgärder är DELETE.
Steg 3: Visa en länk för att ta bort inlägget på sidan Visa inlägg
Vi lägger till en länk Ta bort under beskrivningen av inläggssektionen och visar bara den här länken i inlägg från den aktuella användaren.
HTML: (app / visningar / inlägg / show.html.erb)
<% om current_user.posts.exists? (@ post.id)%> <% = link_to 'Ta bort', post_path (@post), metod:: ta bort, data: {bekräfta: 'Är du säker?' }%> <% slut%>Denna metod för att ta bort länk: ta bort och visa bekräftelsemeddelandet innan du tar bort ett inlägg.
CSS-kod:
.delete {padding-top: 20px; a {font-size: 15px; textdekoration: understrykning; }}Nu ser ut som:
Lägg till Hashtags till Post
Mål:
I det här avsnittet kommer vi att lägga till Hashtags till Post genom att extrahera dem från beskrivningen av Post.
Exempel: När en användare skapar ett inlägg med beskrivningen är "Mina favorit #böcker, bra #moment". Vår applikation kommer att skapa två hashtags är bok och ögonblick.
Strömma:
- Designdatabas
- Skapa HashTag-modell
- Skapa PostHashTag-modell
- Skapa Hashtags för inlägg
Designdatabas:
Vi kan se att varje inlägg kan innehålla en eller många hashtags i beskrivningen. Och varje hashtagg kan användas i ett eller flera inlägg.
- En post har många HashTags: en-till-många-relation
- HashTag tillhör Posts: en-till-många-relation
Det betyder att Post med HashTag har en relation mellan många och många.
Bilden nedan är vår underdatabasdesign. Vi skapar två tabeller: HashTag och PostsHashTag-tabellen. PostsHashTag-tabellen är där lagra information om post och hashtag-relation.
Skapa HashTag-modell
Vi kommer att använda en modellgenerator för att generera en hash_tag-modell med namnfältstypsträngen, en migrering som skapar en hash_tags-tabell och test_unit-filer. Kör kommando:
rails genererar modell hash_tag name: stringUtgången:
åberopa active_record skapa db / migrera / 20181017134507_create_hash_tags.rb skapa app / models / hash_tag.rb anropa test_unit skapa test / models / hash_tag_test.rb skapa test / fixtures / hash_tags.ymlFör Active Record skapar det:
- Modell: app / models / hash_tag.rb
- Migration: db / migrate / 20181017134507_create_hash_tags.rb
Tips: Ibland kanske du inte kommer ihåg exakt format för kommandot för generatorn, du kan använda sorteringskommandot nedan för att se hur du använder:
rails genererar modellKör migrering för att skapa hash_tags-tabellen:
rails db: migreraSkapa PostHashTag-modell
Innan jag skapar den här modellen, berättar jag om en has_many: through association-funktion. Denna förening används ofta för att skapa en många-till-många-anslutning till en annan modell. Det indikerar att den deklarerande modellen kan matchas med noll eller fler instanser av en annan modell genom att gå vidare genom en tredje modell.
I vårt fall: Mellan Post och HashTag är en många-till-många-anslutning och ansluten via en tredje modell är PostHashTag.
Skapa modellen:
rails genererar modell post_hash_tagåberopa active_record skapa db / migrera / 20181017142241_create_post_hash_tags.rb skapa app / models / post_hash_tag.rb anropa test_unit skapa test / models / post_hash_tag_test.rb skapa test / fixtures / post_hash_tags.ymlUppdatera db / migrate / 20181017142241_create_post_hash_tags.rb-filen:
klass CreatePostHashTags t.stämplar end end endVi lägger till ytterligare 2 linjer i migreringsfilen:
t.belongs_to: post, index: true t.belongs_to: hash_tag, index: trueKör migrering:
rails db: migreraMigreringen skapar en post_hash_tags-tabell med fler 2 kolumner är post_id och hash_tag_id och indexerar även 2 dessa kolumner.
Du kan se det i db / schema.rb-filen:
create_table "post_hash_tags", kraft:: kaskad do | t | t.bigint "posts_id" t.bigint "hash_tags_id" t.datetime "create_at", null: false t.datetime "updated_at", null: false t.index ["hash_tags_id"], namn: "index_post_hash_tags_on_hash_tags_id" t.index [ "posts_id"], name: "index_post_hash_tags_on_posts_id" slutFörklara föreningen i Post, HashTag och PostHashTag
I modeller kodar du så här:
klass Post klass PostHashTag klass HashTagKolla våra föreningsdeklarationer:
Vi använder rails konsol för att kontrollera våra förklaringar genom att utföra en fråga. Rails-konsolkommandot hjälper oss att interagera med din Rails-applikation från kommandoraden. Kör kommando:
rails c Laddar utvecklingsmiljö (Rails 5.2.1) 2.4.0: 001>För post:
post = Post.last=> #post.hash_tags # Returnera hash_tags för detta inlägg=> HashTag Load (0,6ms) VÄLJ "hash_tags". * FRÅN "hash_tags" INNER JOIN "post_hash_tags" ON "hash_tags". "Id" = "post_hash_tags". "Hash_tag_id" WHERE "post_hash_tags". "Post_id" = $ 1 LIM $ 2 [["post_id", 33], ["LIMIT", 11]] => #För HashTag:
hash_tag = HashTag.create (namn: "rails")=> #hash_tag.posts # Returnera inlägg med hash_tags=> Postbelastning (0,3ms) VÄLJ "inlägg". * FRÅN "inlägg" INNER JOIN "post_hash_tags" ON "posts". "Id" = "post_hash_tags". "Post_id" WHERE "post_hash_tags". "Hash_tag_id" = $ 1 LIMIT $ 2 [["hash_tag_id", 2], ["LIMIT", 11]] => #Det fungerar!
Skapa Hashtags för inlägg
När en användare skapar ett nytt inlägg med en beskrivning så här: "Jag älskar #ruby, ruby är #wuskigt". Jag förväntar mig att vårt system kommer att skapa 2 hashtags med namn är: rubin och fantastisk.
Steg 1: Extrahera Hashtags från beskrivningen av Post
Lägg till en instansmetod i Post-modellen för att extrahera hashtags:
def extra_name_hash_tags description.to_s.scan (/ # \ w + /). karta {| namn | name.gsub ("#", "")} slutDen här metoden kommer att återgå till en rad namn hashtags. Till exempel:
post = Post.last=> #post.extract_name_hash_tags=> ["rubin", "awesome"]Steg 2: Lägg till en återuppringning för att skapa hashtags efter att du har skapat ett inlägg.
Active Record stöder många användbara återuppringningar.
Vi använder after_commit återuppringning för vår inläggsmodell, denna återuppringning kallas efter att ett inlägg har skapats, uppdaterats eller förstörts. Men nu vill vi bara utlösa detta återuppringning när ett inlägg skapas, så vi lägger till mer: på alternativet för specifikt att skapa åtgärder. Du kan lära dig mer om after_commit i Rails api-dokument.
after_commit: create_hash_tags, på:: skapaDefiniera denna återuppringning i postmodell:
klass Post after_commit: create_hash_tags, on:: create def create_hash_tags # skapa hash_tags för Post end endMetoden create_hash_tags kommer att kallas efter att ett inlägg har skapats. Lägg till logik till denna metod:
def create_hash_tags extract_name_hash_tags.each do | name | hash_tags.create (namn: namn) slutändandef extra_name_hash_tags description.to_s.scan (/ # \ w + /). karta {| namn | name.gsub ("#", "")} slutFörklara create_hash_tags-metoden:
- Metoden skapar hashtags relaterade till ett inlägg baserat på resultatet av metoden extract_name_hash_tags.
- Rad hash_tags.create (namn: namn): Eftersom ett inlägg har många hash-taggar, genom post_hash_tags-tabellen, skapar denna radkod en ny HashTag-post (H) och en ny PostHashTag-post som innehåller hash_tag_id som just skapats (H.id) och post_id är nuvarande inläggs-id.
Slutligen ser Post-modellen så här:
klass Inlägg def create_hash_tags extract_name_hash_tags.each do | name | hash_tags.create (namn: namn) slutändandef extra_name_hash_tags description.to_s.scan (/ # \ w + /). karta {| namn | name.gsub ("#", "")} slutändanNu kommer vi tillbaka till vår ansökan, lägger till ett nytt inlägg och ser resultaten.
Sök inlägg
Mål:
För det här avsnittet kommer vi att implementera:
- Sökfunktion som hjälper användare att söka inlägg efter hashtag (#) eller beskrivning av inlägg.
- Aktivera hashtags i postbeskrivningen, gör att det är klickbart för att söka sidan.
Skapa sökkontroller med indexåtgärd:
rails g controller Sökindex - no-javascripts - no-stylesheets - no-helperUppdatera till rutter:
get 'search' => 'search # index'Lägg till search_path till sökformuläret:
<% = form_med url: search_path, metod:: get, local: true, class: 'form-inline search-form' do | form | %> <% = form.text_field: fråga, värde: params [: fråga], klass: 'form-control mr-sm-2', platshållare: '#search'%> <% end%>I Search Controller: (app / controllers / search_controller.rb)
Vi ska söka inlägg efter hashtagnamn eller beskrivning.
klass SearchControllerFall 1: Sök med en hashtag (#travel), vi returnerar inlägg som har hashtags namn är fråga värde.
Frågeställningar:
query = params [: query] .gsub ('#', '')Post.joins (: hash_tags) .where (hash_tags: {name: query})Detta ger:
# fråga = "rubin"VÄLJ "inlägg". * FRÅN "inlägg" INNER JOIN "post_hash_tags" ON "post_hash_tags". "Post_id" = "posts". "Id" INNER JOIN "hash_tags" ON "hash_tags". "Id" = "post_hash_tags". " hash_tag_id ”WHERE“ hash_tags ”.” name ”= $ 1 LIMIT $ 2 [[“ name ”,“ ruby ”], [“ LIMIT ”, 11]]Fall 2: Sök efter beskrivning (inte en hashtag), vi returnerar inlägg som har beskrivning innehåller frågan.
@posts = Post.where ("beskrivning som?", "% # {params [: fråga]}%")Du kan lära dig mer fråga i: guider.rubyonrails.org/active_record_querying
I Visa: (app / views / search / index.html.erb)
<% om @ posts.exists? %> Top Posts <% annars%> Oop! Inga matchande inlägg ... <% slut%><% @ posts.each do | post |%> <% = image_tag post.image%> <% slut%>Visa Hashtags i postbeskrivning
Vi gör hashtags är klickbara och länkar till sökningar i denna hashtag. Ändra inläggets beskrivning på hemsidan och inläggssidan:
<% = post.beskrivning%>till
<% post.description.to_s.split ('') .each do | word | %> <% om word.start_with? ('#')%> <% = link_to word, search_path (fråga: word)%> <% else%> <% = word%> <% end%> <% end% >Nu ser ett inlägg ut:
Slutsats
I den här artikeln, jag guider dig att lära dig om Association in Active Record, särskilt has_many: through association. Och hur man hämtar data från databasen med Active Record. Jag hoppas att du kan förstå djupare om Active Record.
Källkod på Github: https://github.com/thanhluanuit/instuigram
referenser:
- Associering i aktiv post: https://guides.rubyonrails.org/association_basics.html
- Aktivt inspelningsfrågorgränssnitt: https://guides.rubyonrails.org/active_record_querying.html