Początek przygody - problemy z migracjami

Cześć,
długo zwlekałem z założeniem konta tutaj i starałem się samodzielnie walczyć z problemami. Jednak teraz nie wiem kompletenie jak to ruszyć. Aktualnie w mojej aplikacji mam problem z N+1 Count:

w modelu post.rb:

belongs_to :player, counter_cache: true

w modelu player.rb:

has_many :posts

Z tego co rozumiem z dokumentacji przy zastosowaniu metody player.posts.count powinno podać liczbę postów z cache przeglądarki - czyli wykonać się natychmiastowo. Jednak dla każdego playera nadal wykonuje liczenie.
Dodatkowo, przy próbie dodania nowego postu z rails C wyrzuca błąd, że posts_count nie może być pusty

http://guides.rubyonrails.org/association_basics.html#counter-cache mówi że counter_cache odpowiada na .size a nie .count

@mentero :
zrobiłem teraz player.posts.size w widoku

z tego co rozumiem, powinno działać dopiero po dodaniu nowego postu do bazy.
zwraca błąd (przy dodawaniu postu przez konsole):

   (0.1ms)  ROLLBACK
ActiveRecord::StatementInvalid: PG::UndefinedColumn: BŁĄD:  kolumna "posts_count" nie istnieje

model:

belongs_to :player, counter_cache: true

1 Like

Migracja dodająca kolumnę posts_count do tabeli players ?

rake db:migrate niestety nic nie wykonuje

Ok. A czy masz taką migrację? Sama z siebie się ona nie stworzy.

@Skippo
A co rake db:migrate ma wykonywać? Musisz własnoręcznie dodać tą kolumne do bazy danych.

Możesz też wybrać kolumne w której counter będzie przechowywany
http://guides.rubyonrails.org/association_basics.html
4.1.2.3 :counter_cache

belongs_to :customer, counter_cache: :count_of_orders

http://railscasts.com/episodes/23-counter-cache-column?view=asciicast

Ja to tylko tutaj tak zostawię.

Jak dodam ręcznie kolumnę do bazy to po wykonaniu rake db:migration przez inną osobę kolumna się usunie?

Migracje nie działają w taki sposób.

  • Jeżeli dodasz ręcznie kolumne to migracje Ci jej nie usunął (no chyba że dodasz migracje usuwającą :))
  • Ktoś inny kto ściągnie projekt nie będzie miał poprostu takiej bazy jak Ty, bo będzie miał stworzoną baze przez migracje (a Ty dodatkowo będziesz miał tą jedną kolumne którą sam dodałeś)

ok, dodałem taką migrację:

class AddPostsCounterToPlayer < ActiveRecord::Migration
  def change
    create_table :players do |t|
      t.integer :posts_count

      t.timestamps null: false
    end
  end

end

wyrzuca mi błąd:

PG::DuplicateTable: BŁĄD:  relacja "players" już istnieje

czy mogę utworzyć nową migrację, czy mam dopisać kolumnę do starej?

Usuń to i zamień swoją metode change na:

def change
add_column :players, :posts_count, :integer
end

Powinno dodać Ci tą kolumne.

Twoja migracja probuje stworzyć tabele z takimi kolumnami - masz już stworzoną taką tabele. Do dodawania kolumn służy “add_column”, do usuwania “remove_column”.

Robiłeś jakiś tutorial już ? Może powinieneś od tutoriali zacząć a nie od własnej aplikacji? :smile:

To już w sumie moja 3 appka. Przedtem robiłem CMS-y, gdzie w sumie wszystko ze scaffolda/ generate model było.

Zrobiłem i rzeczywiście pomogło. Teraz przy próbie wywołania:

Dla każdego playera:

= player.posts_count

zwraca mi pusty element tabeli

Ok działa, ogarniam już :slight_smile: