trashyEx
Ecto: many_to_many timestamps
Hello,
How do I use correctly the many_to_many association with timestamps?
I suppose it uses insert_all (or update_all) under the put_assoc and it is the reason it doesn’t provide inserted_at and modified_at.
The schemas:
defmodule A.User do
use Ecto.Schema
import Ecto.Changeset
alias A.Product
schema "users" do
field :name, :string
many_to_many :products, Product, join_through: "users_products"
timestamps()
end
@doc false
def changeset(user, attrs) do
user
|> cast(attrs, [:name])
|> validate_required([:name])
end
end
defmodule A.Product do
use Ecto.Schema
import Ecto.Changeset
schema "products" do
field :name, :string
timestamps()
end
@doc false
def changeset(product, attrs) do
product
|> cast(attrs, [:name])
|> validate_required([:name])
end
end
defmodule A.UserProduct do
use Ecto.Schema
import Ecto.Changeset
alias A.User
alias A.Product
schema "users_products" do
belongs_to :user, User
belongs_to :product, Product
timestamps()
end
@doc false
def changeset(user_product, attrs) do
user_product
|> cast(attrs, [])
|> validate_required([])
end
end
The users_products migration:
def change do
create table(:users_products) do
add :user_id, references(:users, on_delete: :nothing)
add :product_id, references(:products, on_delete: :nothing)
timestamps()
end
create unique_index(:users_products, [:user_id, :product_id])
create index(:users_products, [:user_id])
create index(:users_products, [:product_id])
end
The association:
IO.puts("querying")
product = from q in Product,
where: q.name == ^product_name
product = Repo.one(product)
IO.inspect(product, label: "product:")
IO.puts("querying")
user = from q in User,
where: q.name == ^user_name,
preload: :products
user = Repo.one(user)
IO.inspect(user, label: "user:")
if product != nil and user != nil do
cs = Ecto.Changeset.change(user)
cs = Ecto.Changeset.put_assoc(cs, :products, [product | user.products])
IO.inspect(cs, label: "assoc put")
Repo.update!(cs)
end
The error:
[debug] QUERY OK db=0.2ms queue=0.1ms
begin []
[debug] QUERY ERROR db=9.2ms
INSERT INTO "users_products" ("product_id","user_id") VALUES ($1,$2) [1, 1]
[debug] QUERY OK db=0.1ms
rollback []
** (Postgrex.Error) ERROR 23502 (not_null_violation): null value in column "inserted_at" violates not-null constraint
table: users_products
column: inserted_at
Failing row contains (4, 1, 1, null, null).
I am up with other ways to achieve this. I don’t mind to use more explicit forms, but I need flexibility to add/remove/modify the associations, for example something like:
# Check if exists
up = from q in UserProduct,
where: q.user == ^user.id and q.product == ^product.id
up = Repo.one(up)
IO.inspect(up, label: "user_product")
# Create an association
up = Products.create_user_product(%{"user_id" => 1, "product_id" => 2})
Repo.insert!(up)
But it says UserProduct contains virtual fields (belongs_to), and I don’t know if it is natural to change it to field when they don’t belong in UserProduct but User and Product.
Most Liked
idi527
Maybe try replacing it with
many_to_many :products, Product, join_through: A.UserProduct
3
Popular in Questions
What is the proper way to load a module from a file in to IEX?
In the python world, doing something like this pretty standard:
from ....
New
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
Hi all,
Trying to get some more clarity over utc_datetime and naive_datetime for Ecto:
https://hexdocs.pm/ecto/Ecto.Schema.html#module-...
New
i’m a new one to elixir
which editor can i use
vs code? or atom?
Thanks! :smiley:
New
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
New
Hi all,
I've just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage.
I'm trying to use Postg...
New
Hi,
I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
After calling mix ecto.create I get this error:
17:00:32.162 [error] GenServer #PID<0.412.0> terminating
** (Postgrex.Error) FATAL...
New
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
Other popular topics
Good day to you all.
I have been struggling to get a query involving like and ilike to work.
Can anyone assist me on this, please?
pro...
New
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine)
This is a plugin that adds support for Elixir to JetBrains IntelliJ...
New
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
The Elixir Typespec docs show the following syntax for keyword lists in typespecs:
# ...
| [key: type] # keyword lis...
New
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
Hello everybody,
usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including.
What is Phoenix LiveV...
New
by Lance Halvorsen
Elixir and Phoenix are generating tremendous excitement as an unbeatable platform for building modern web application...
New







