2016-02-17 14 views
6

Korzystanie z frameworka, :id, :integer zostanie wygenerowane automatycznie. http://www.phoenixframework.org/docs/ecto-custom-primary-keysDostosowywanie identyfikatora Phoenix

Ale chcę nie generowane automatycznie i użyć niestandardowego pola id, np :id, :string, podobnie jak to http://ruby-journal.com/how-to-override-default-primary-key-id-in-rails/

Aby ustawić

defmodule MyApp.Item do 
    use MyApp.Web, :model 

    # @primary_key {:id, :id, autogenerate: false} 
    schema "items" do 
    field :id, :string, autogenerate: false # some unique id string 
    field :type, :integer 

Podnosi ** (ArgumentError) field/association :id is already set on schemahttps://github.com/elixir-lang/ecto/blob/db1f9ccdcc01f5abffcab0b5e0732eeecd93aa19/lib/ecto/schema.ex#L1327

+0

to wydaje 'tworzyć table (: items, primary_key: false) czy w pliku migracji ...? http://www.phoenixframework.org/docs/ecto-custom-primary-keys – otiai10

Odpowiedz

6

Są dwa problemy, z którymi miałem do czynienia.

  1. Obie klauzule @primary_key {:id, :id, autogenerate: false} i fields :id nie mogą być w definicji schematu.

To rozwiązanie

defmodule MyApp.Item do 
    use MyApp.Web, :model 

    @primary_key {:id, :string, []} 
    schema "items" do 
    # field :id, :string <- no need! 
  1. uniknąć automatycznie wygenerowany identyfikator, po prostu trzeba zmieniać pliku migracji

Ci się to

defmodule MyApp.Repo.Migrations.CreateItem do 
    use Ecto.Migration 

    def change do 
    create table(:items, primary_key: false) do 
     add :id, :string, primary_key: true 

Wreszcie mogę wykonać mix ecto.migrate i mogę uzyskać definicje tabel cja poniżej

mysql> SHOW CREATE TABLE items; 
| items | CREATE TABLE `builds` (
    `id` varchar(255) NOT NULL, 

oficjalny dokument z pewnością mówi o tym http://www.phoenixframework.org/docs/ecto-custom-primary-keys

Rzućmy okiem na pierwszy migracji, priv/repo/migracje/20150908003815_create_player.exs. Będziemy musieli zrobić dwie rzeczy. Pierwszym z nich jest przekazanie drugiego argumentu - primary_key: false do funkcji table/2, aby nie utworzył on klucza primary_key. Następnie musimy przekazać primary_key: true do funkcji add/3 dla pola name, aby zasygnalizować, że będzie to klucz primary_key.

Ale na początku, nie chcesz kolumna id, wystarczy zrobić create table(:items, primary_key: false) w migracji i edytować schemat

defmodule MyApp.Item do 
    use MyApp.Web, :model 

    # @primary_key {:id, :string, []} 
    @primary_key false # to avoid unnecessary IO scanning 
    schema "items" do 
    # field :id, :string <- no need! 

Choć samo rozwiązany, i tak dzięki

+1

Jeśli ustawisz niestandardowy identyfikator podstawowy podczas migracji, dlaczego nie chcesz go ustawić? Czy stanie się on niedostępny dla dalszych zapytań, np. Z absyntem (graphql)? @ otiai10 – StevenV

+0

Czy mogę zapytać, jak ustawić wartość "id"? W kontrolerze lub w definicji modelu? –

+1

@SvenvenV To było tak specyficzne dla projektu rozwiązanie i tylko na samym początku mojego projektu, więc użyłem właśnie migracji do zmiany (jak pamiętam). Zdefiniowanie go w schemacie może działać. – otiai10