Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to customize id of Phoenix

Using phoenix framework, :id, :integer would be generated automatically. http://www.phoenixframework.org/docs/ecto-custom-primary-keys

But I want it not auto-generated and use custom id field, for example :id, :string, much like this http://ruby-journal.com/how-to-override-default-primary-key-id-in-rails/

To set the

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

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

like image 657
otiai10 Avatar asked Feb 17 '16 02:02

otiai10


1 Answers

There are two problems I was facing.

  1. Both of @primary_key {:id, :id, autogenerate: false} and fields :id clause cannot be in schema definition.

This is the solution

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

  @primary_key {:id, :string, []}
  schema "items" do
    # field :id, :string <- no need!
  1. to avoid auto-generated id, I just have to edit migration file

Like this

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

Finally, I can execute mix ecto.migrate and can get table definition below

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

Official document certainly says about that http://www.phoenixframework.org/docs/ecto-custom-primary-keys

Let's take a look at the migration first, priv/repo/migrations/20150908003815_create_player.exs. We'll need to do two things. The first is to pass in a second argument - primary_key: false to the table/2 function so that it won't create a primary_key. Then we'll need to pass primary_key: true to the add/3 function for the name field to signal that it will be the primary_key instead.

But at the beginning, you don't want column id, you just do create table(:items, primary_key: false) in migration, and edit schema

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!

Though self-resolved, thanks anyway

like image 140
otiai10 Avatar answered Nov 03 '22 11:11

otiai10