Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

...warning: Ecto.Changeset.cast/4 is deprecated, please use cast/3 + validate_required/3 instead #35

Closed
nelsonic opened this issue Feb 19, 2017 · 4 comments

Comments

@nelsonic
Copy link
Member

nelsonic commented Feb 19, 2017

running mix test on page 134
but get the following warning message:

...warning: `Ecto.Changeset.cast/4` is deprecated, please use `cast/3` + `validate_required/3` instead
    (rumbl) web/models/video.ex:22: Rumbl.Video.changeset/2
    test/models/video_test.exs:15: Rumbl.VideoTest."test changeset with invalid attributes"/1
    (ex_unit) lib/ex_unit/runner.ex:296: ExUnit.Runner.exec_test/1
    (stdlib) timer.erl:166: :timer.tc/1

.warning: `Ecto.Changeset.cast/4` is deprecated, please use `cast/3` + `validate_required/3` instead
    (rumbl) web/models/video.ex:22: Rumbl.Video.changeset/2
    test/models/video_test.exs:10: Rumbl.VideoTest."test changeset with valid attributes"/1
    (ex_unit) lib/ex_unit/runner.ex:296: ExUnit.Runner.exec_test/1
    (stdlib) timer.erl:166: :timer.tc/1

image

Looked at: https://hexdocs.pm/ecto/Ecto.Changeset.html

tried changing the code in web/models/video.ex:20-25 from:

  def changeset(struct, params \\ %{}) do
    struct
    |> cast(params, @required_fields, @optional_fields)
    |> assoc_constraint(:category)
  end

To:

  def changeset(struct, params \\ %{}) do
    struct
    |> cast(params, @optional_fields)
    |> validate_required(params, @required_fields)
    |> assoc_constraint(:category)
  end

or:

  def changeset(struct, params \\ %{}) do
    struct
    |> cast(params, [@required_fields, @optional_fields]) # cast all fields as a single list
    |> validate_required(params, @required_fields)
    |> assoc_constraint(:category)
  end

but tests failed:
image

figured I need to call cast on all the fields as a single list.
read http://learningwithjb.com/posts/concat-lists-with-elixir
So changed to:

  @required_fields ~w(url title description)
  @optional_fields ~w(category_id)
  @all_fields ~w(url title description category_id) # obviously not "DRY"

  @doc """
  Builds a changeset based on the `struct` and `params`.
  """
  def changeset(struct, params \\ %{}) do
    struct
    |> cast(params, @all_fields)
    |> validate_required(@required_fields)
    |> assoc_constraint(:category)
  end

and ran: mix test and got:
test fail

I would like to continue spending time on this but I suspect that it will become clear to me later in the book or through more practice/understanding so I'm just going to leave this issue open in case someone else knows how to "fix" it ...

@samhstn
Copy link
Member

samhstn commented Feb 26, 2017

@nelsonic I may be totally off the mark, but what happens if you change:

|> validate_required(params, @required_fields)

to

|> validate_required(@required_fields)

I tried something similar to that and it seemed to work (I'm not as far through the book as you so I can't run the example you are running just yet).

nelsonic added a commit that referenced this issue Feb 26, 2017
@Jbarget
Copy link
Member

Jbarget commented Mar 3, 2017

For anyone following "Programming Pheonix" around page 60:

@des-des and I were running into the same warnings and ended up doing the below

  def changeset(model, params \\ :invalid) do
    model
    |> cast(params, ~w(name username))
    |> validate_required([:name, :username])
    |> validate_length(:username, min: 1, max: 20)
  end

params is injected as the first argument to validate_required

@untra
Copy link

untra commented Mar 5, 2017

I would add to that: the book adds a uniqueness index to the username field, but doesn't suggest a way to validate that uniqueness:

 def changeset(model, params \\ :invalid) do
    model
    |> cast(params, ~w(name username))
    |> validate_required([:name, :username])
    |> unique_constraint(:username)
    |> validate_length(:username, min: 1, max: 20)
  end

I would recommend also adding the |> unique_constraint(:username) to the username validations

@nelsonic
Copy link
Member Author

nelsonic commented Mar 6, 2017

@untra thanks for sharing. I have a slight variation on this:

 def changeset(model, params \\ :invalid) do
    model
    |> cast(params, ~w(name username))
    |> validate_required([:name, :username])
    |> validate_length(:username, min: 1, max: 20)
    |> unique_constraint(:username) # save the unique_constraint for last as it "hits" the DB. ;-)
  end

@iteles iteles closed this as completed in #42 Mar 6, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants