Zmiana typu kolumny na dłuższe ciągi w szynach

Przy pierwszej migracji zadeklarowałem na kolumnie content jako string Activerecord tworzy ciąg znaków (255) według adnotacji gem.

Po wciśnięciu aplikacji do heroku, która używa postgres, jeśli w formularzu w treści wpisuję ciąg dłuższy niż 255, to dostaję błąd

PGError: ERROR: value too long for type character varying(255)

Problem polega na tym, że treść musi zawierać łańcuch, który może być bardzo długi (wolny tekst, może być tysiące znaków)

  1. What variable (is string is not appropriate za to) czy pg zaakceptuje?
  2. Jak utworzyć migrację, aby zastąpić Typ tej kolumny

Dzięki

Author: mu is too short, 2012-01-01

2 answers

Powinieneś używać {[2] } z Rails, jeśli chcesz ciąg bez limitu długości. Taka migracja:

def up
  change_column :your_table, :your_column, :text
end
def down
  # This might cause trouble if you have strings longer
  # than 255 characters.
  change_column :your_table, :your_column, :string
end

Powinno się wszystko uporządkować. Możesz też chcieć :null => false lub innych opcji na końcu.

Kiedy używasz Kolumny string bez wyraźnego limitu, Rails doda do niejawną :limit => 255. Ale jeśli użyjesz text, otrzymasz dowolny ciąg o dowolnej długości, który obsługuje baza danych. PostgreSQL pozwala na użycie varchar kolumny bez długości, ale większość baz danych używa oddzielny typ dla tego i Rails nie wie o varchar bez długości. Musisz użyć text w Rails, aby uzyskać text kolumna W PostgreSQL. Nie ma różnicy w PostgreSQL między kolumną typu text a kolumną typu varchar (ale varchar(n) jest inny). Co więcej, jeśli wdrażasz PostgreSQL, nie ma powodu, aby w ogóle używać :string (AKA varchar), baza danych traktuje text i varchar(n) tak samo wewnętrznie, z wyjątkiem dodatkowych ograniczeń długości dla varchar(n); powinieneś używać tylko varchar(n) (AKA :string), Jeśli masz zewnętrzne ograniczenie (takie jak formularz rządowy, który mówi, że pole 432 na formularzu 897/B będzie miało 23 znaki) w rozmiarze kolumny.

Na marginesie, jeśli używasz w dowolnym miejscu Kolumny string, zawsze należy podać :limit jako przypomnienie sobie, że istnieje limit i powinieneś mieć walidację w modelu, aby upewnić się, że limit nie zostanie przekroczony. Jeśli przekroczysz limit, PostgreSQL będzie narzekał i podnosił wyjątek, MySQL po cichu obetnie łańcuch lub złoży skargę (w zależności od konfiguracji serwera), SQLite przepuści go tak, jak jest, a inne bazy danych zrobią coś innego (prawdopodobnie będą narzekać).

Ponadto, powinieneś również rozwijać, testować i wdrażać na tej samej bazie danych (która zwykle będzie PostgreSQL w Heroku), powinieneś nawet używać tych samych wersji serwera baz danych. Istnieją inne różnice między bazami danych (np. zachowanie GROUP BY), które ActiveRecord cię nie odizoluje. Może już to robisz, ale pomyślałem, że i tak o tym wspomnę.


Update : nowsze wersje ActiveRecord rozumieją varchar bez ograniczeń, więc z PostgreSQL przynajmniej można powiedzieć:

change_column :your_table, :your_column, :string, limit: nil

Aby zmienić kolumnę varchar(n) na varchar. text i varchar to nadal to samo co w PostgreSQL, ale niektórzy konstruktorzy formularzy będą traktować je inaczej: varchar otrzymuje <input type="text">, podczas gdy text otrzymuje multi-line <textarea>.

 217
Author: mu is too short,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-09-21 17:08:53

Chociaż przyjęta odpowiedź jest doskonała, chciałem dodać odpowiedź tutaj, że mam nadzieję, że lepiej radzi sobie z oryginalnymi plakatami pytanie część 2, Dla Nie ekspertów jak ja.

  1. Jak utworzyć migrację, aby zastąpić Typ tej kolumny

Generowanie migracji rusztowań

Możesz wygenerować migrację do przechowywania zmian, wpisując w konsoli (po prostu zastąp table dla nazwy tabel, a column dla Ciebie nazwa kolumny)

rails generate migration change_table_column

Wygeneruje to migrację szkieletu wewnątrz folderu Rails application /db/migrate/. Ta migracja jest symbolem zastępczym dla kodu migracji.

Na przykład chcę utworzyć migrację, aby zmienić typ kolumny z string na text, w tabeli o nazwie TodoItems:

class ChangeTodoItemsDescription < ActiveRecord::Migration
  def change
     # enter code here
     change_column :todo_items, :description, :text
  end
end

Uruchamianie migracji

Po wpisaniu kodu do zmiany kolumny Uruchom:

rake db:migrate

Aby zastosować migrację. Jeśli zrobisz błąd, który zawsze możesz cofnąć za pomocą:

rake db:rollack

Metody Up and Down

Przyjęta odpowiedź odwołuje się do metod Up i Down, zamiast do nowszej metody Change. Od rails 3.2 metody w górę i w dół old style prezentowały kilka zalet w stosunku do nowszej metody zmiany. "Góra i dół" unikać ActiveRecord::IrreversibleMigration exception. Od wydania Rails 4 możesz użyć reversible aby uniknąć tego błędu:

class ChangeProductsPrice < ActiveRecord::Migration
  def change
    reversible do |dir|
      change_table :products do |t|
        dir.up   { t.change :price, :string }
        dir.down { t.change :price, :integer }
      end
    end
  end
end

Enjoy Rails:)

 8
Author: Tony Cronin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-16 17:52:28