如何自定义Phoenix的id

oti*_*i10 8 elixir phoenix-framework

使用phoenix框架,:id, :integer会自动生成. http://www.phoenixframework.org/docs/ecto-custom-primary-keys

但我希望它不会自动生成并使用自定义ID字段,例如:id, :string,像这样 http://ruby-journal.com/how-to-override-default-primary-key-id-in-rails/

设置

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
Run Code Online (Sandbox Code Playgroud)

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

oti*_*i10 12

我面临两个问题.

  1. 这两个@primary_key {:id, :id, autogenerate: false}fields :id条款不能在模式定义.

这是解决方案

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

  @primary_key {:id, :string, []}
  schema "items" do
    # field :id, :string <- no need!
Run Code Online (Sandbox Code Playgroud)
  1. 为了避免自动生成的id,我只需要编辑迁移文件

像这样

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
Run Code Online (Sandbox Code Playgroud)

最后,我可以执行mix ecto.migrate并可以在下面获得表定义

mysql> SHOW CREATE TABLE items;
| items | CREATE TABLE `builds` (
  `id` varchar(255) NOT NULL,
Run Code Online (Sandbox Code Playgroud)

官方文件肯定会说明 http://www.phoenixframework.org/docs/ecto-custom-primary-keys

我们先来看看迁移,priv/repo/migrations/20150908003815_create_player.exs.我们需要做两件事.第一个是将第二个参数 - primary_key:false传递给table/2函数,这样它就不会创建primary_key.然后我们需要将primary_key:true传递给name字段的add/3函数,以表示它将是primary_key.

但是在开始时,您不需要列id,您只需要create table(:items, primary_key: false)迁移,并编辑模式

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!
Run Code Online (Sandbox Code Playgroud)

虽然自我解决,但无论如何,谢谢