Hi,
I’m currently trying ecto and i got a problem.
I generated REST JSON API, with foreign key constraints using CLI.
I have Topic and User
My schemas :
defmodule Api.Forum.Topic do
use Ecto.Schema
import Ecto.Changeset
schema "topics" do
field(:body, :string)
field(:title, :string)
field(:user_id, :integer, null: false)
timestamps()
end
@doc false
def changeset(topic, attrs) do
topic
|> cast(attrs, [:title, :body])
|> validate_required([:title, :body])
end
end
defmodule Api.Users.User do
use Ecto.Schema
import Ecto.Changeset
schema "users" do
field(:name, :string)
has_many(:topics, EkklesiaApi.Forum.Topic)
timestamps()
end
@doc false
def changeset(user, attrs) do
user
|> cast(attrs, [:name])
|> validate_required([:name])
end
end
and migrations :
defmodule Api.Repo.Migrations.CreateUsers do
use Ecto.Migration
def change do
create table(:users) do
add :name, :string
timestamps()
end
end
end
defmodule Api.Repo.Migrations.CreateTopics do
use Ecto.Migration
def change do
create table(:topics) do
add :title, :string
add :body, :text
add :user_id, references(:users, on_delete: :nothing)
timestamps()
end
create index(:topics, [:user_id])
end
end
Can’t understand why inserting {title: “Foo”, body: “bar”, user_id: 1} only insert title and body
It’s to encourage the usage of manually/on-site using things like put_assoc, which I personally don’t prefer as that tends to require having to load the association, so I do it the way that you are trying to too personally.
Heh, honestly I’d say that if you do have both rows already queried then put_assoc is better (if using a reference in the schema, otherwise not) as it will check types and such locally, otherwise setting directly is good as the DB will check it anyway for you.
Is there any reason that phoenix does not add these fields by default in validation ?
Casting foreign keys from outside data can open you up for some nasty vulnerabilities.
I saw a project that casted something like shop_id in their changesets and I could do whatever I wanted with them since I was practically “the owner” of every shop in their database.
The fact that it’s so easy to do in ecto + phoenix is a bit worrisome.
Yeah don’t just put everything in a changeset, only cast the things that you explicitely want, otherwise anyone outside can just submit whatever data they want to your database anyway! I kind of wish that Phoenix/Ecto didn’t generate changeset functions in their schema’s to be honest…