acrolink

acrolink

I have a special need to set the id of newly created entities to some integer relating to UNIX timestamp (not autoincrement based). Any idea how to do this? i am using Phoenix 1.3. Thank you.

Showing Posts 1 to 10

idi527

idi527

Are you asking about ecto or elixir’s structs?

With structs you can add something like a new function to return them somewhat prepopulated

defmodule Entity do
  defstruct [:name, :timestamp]
  
  def new(name) do
    %__MODULE__{
      name: name,
      timestamp: NaiveDateTime.utc_now()
    }
  end
end

And you can use @primary_key attribute to configure the schema’s primary key.

@primary_key {:your_id, :id, autogenerate: false}
acrolink

acrolink OP

I have tried your code but it fails. defstruct .. gives an error defstruct has already been called for Entre.Warehouse.Item, defstruct can only be called once per module and if I omit that line and keep the def new(name) do block I get Entre.Warehouse.Item.__struct__/1 is undefined, cannot expand struct Entre.Warehouse.Item.

I am using Phoenix 1.3. I am not sure if the errors I get are related to the newly introduced contexts.

idi527

idi527

Sorry, I’ve probably confused you …

The example with defstruct that I’ve provided seems to not be what you want. I just wondered if you were asking about ecto or elixir structs.

Judging by the error you get, you were asking about ecto.

To get custom ids you should use @primary_key.

tomconroy

tomconroy

voger

voger

@idi527: Sorry, I accidentally hit reply in your post. This reply was meant for the original post.

If your question is about how to do custom primary keys with Ecto then here is a guide in phoenix blog
http://phoenixframework.org/blog/custom-primary-key

acrolink

acrolink OP

I am going to use the id field itself but instead of having auto-generated serial values I want to set Unix timestamps as ids. I am using Ecto. I understand that the place to set the value is inside the model definition file but still cannot figure out the way to do that. The Postgres solution can do the job, but I am interested in knowing how to do that in Phoenix. Any help is highly appreciated. Thank you.

voger

voger

In the blog post that I linked it says how to edit the migration

defmodule Hello.Repo.Migrations.CreatePlayer do
  use Ecto.Migration

  def change do
    create table(:players, primary_key: false) do
      add :name, :string, primary_key: true
      add :position, :string
      add :number, :integer

      timestamps
    end
  end
end

If I am not mistaken there is nothing stopping you from naming your primary key “id”. I haven’t tried naming a custom primary key “id”. You have to experiment a bit with this :).

Also if you look in the add/3 documentation you will see it can take the option :default

the column’s default value. can be a string, number or a fragment generated by fragment/1

So you can use that to apply the Postgres function.

acrolink

acrolink OP

@voger

I am just looking at the whole thing from a RoR background. There I could just do self.id = n and that’s all :slight_smile: Here it looks like the more professional way to do this is inside the schema definition and possibly by PostgreSQL itself. My little question in the meantime, fragment/1 uses a PostgreSQL function/procedure or can it consume a value returned from an Elixir function?

voger

voger

Fragment runs SQL code/functions as prepared statements. You can use it if you want to use a custom Postgresql function to handle your ID generation inside the database. Here is an example about using fragments in Ecto: Fragments in Ecto – Learning Elixir

If you wan’t to handle ID generation with an Elixir function you don’t need a fragment. You can use put_change/3 in your changeset in your schema when you create it.

Another option is, if you want to make your code cleaner, you can use a custom ecto type as your field and define an autogenerate/0 function. This way you will still be generating your code with Elixir but you will be able to use that type of field in different structs. Here is an example of using uuids for primary key https://blog.fourk.io/uuids-as-primary-keys-in-phoenix-with-ecto-and-elixir-1dd79e1ecc2e. This example looks a bit like what you are trying to achieve. Also here is the code for the UUID type. Notice how it defines an autogenerate/0 function that just calls generate/0.

Disclaimer: I haven’t actually had the chance to use a custom field.

acrolink

acrolink OP

@voger

Thank you for the valuable information. I have tried to use the put_change/3 inside def changeset(%Item{} = item, attrs) do. It works sort of. It sets the value at the time the form is rendered, not when the entity is saved to the database. In my situation, the value is time related so it should reflect the time when an entity is saved.

I guess, first and 3rd solutions you described can help me achieve the desired result. I have considered setting the value inside the create function. I am not sure if that’s a proper way to do it. I am not sure even how that can be done.

UPDATE

I have just realized that setting the id in the controller is not possible, it must be done either in DB, by custom data-type as suggested by @voger or by some other model way.

Where Next? Top

Trending in Questions Top

stjefim
Hello! Suppose you are building workflow (order / task / payment) processing system with the following requirements: Each workflow con...
New
Blokh
Hey guys, I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly Do you guys have any suggestions what is the best prac...
New
kszambelanczyk
Hello! Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app. I creat...
New
Onor.io
I have what I’ve heard referred to as a “lookup table” in my database. This is a way of assigning codes to common values. One common lo...
New
jaybe78
Hello, I’m developing a online persistent chat system (what’s app) like using elixir/dynamodb/aws for a mobile app(flutter). The diffic...
New
Trolleger
What approach to take when sending live updates to “random” users Hi! I have a question, I have a little chat app, and when I create a DM...
New
widianto
I think I’ve found a small improvement I could contribute to <%= web_namespace %>.CoreComponents (installer/templates/phx_web/compo...
New

Other Trending Topics Top

garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
wintermeyer
There are three potential reasons for members of this forum to have a look at https://vutuv.de You are tired or annoyed of LinkedIn. Yo...
New
webofbits
Aludel - LLM Evaluation Workbench Aludel is an embeddable Phoenix LiveView dashboard for evaluating and comparing LLM prompts across mult...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews