1
votes

I've started recently to work with phoenix, the fact is i'm usually working with NO SQL databases.

I'm working on a classic blog to integrate associations. I've created a basic association :

  • A post belongs to a category
  • A category as many posts

Here are those schemas :

schema "categories" do
    field :category_name, :string
    field :logo, :string
    has_many :posts, Lclp.Post

    timestamps()
  end

schema "posts" do
 field :author, :string
 field :content, :string
 field :content_raw, :string
 field :desc, :string
 field :logo, :string
 field :title, :string
 belongs_to :category, Lclp.Category

 timestamps()
end

This one, working fine, i can call the category name from the category_id of a post after a preload.

The problem is when inserting a post, i've created a form for create a post where i can select the category, set the title, etc... My controller get all the data by pattern matching :

def create_post(conn, %{"post" => post}) do
      IO.inspect(post)
      changeset = Lclp.Post.add_post(%Lclp.Post{}, post)
      IO.inspect(changeset)

      case Lclp.Repo.insert(changeset) do
        {:ok, data} ->
          conn
          |> put_flash(:info, "Post bien ajouté")
          |> redirect(to: adminpost_path(conn, :index))
        {:error, changeset} ->
          conn
          |> assign(:section, "Creation d'un post (callback error)")
          |> render("new.html", changeset: changeset, categories_tab: Lclp.Category.get_categories_name)
      end
    end

All fields are added to the DB except the category_id and which stay at NULL.

The only solution i found out to insert a category_id is that one :

def changeset(post, attrs \\ %{}) do
    post
    |> cast(attrs, [:title, :author, :desc, :content, :content_raw, :logo])
    |> validate_required([:title, :author, :desc, :content, :content_raw])
  end

  def add_post(post, attrs) do
    post
    |> changeset(attrs)
    |> change(%{category_id: String.to_integer(Map.fetch!(attrs, "category_id"))})
  end

Which work well, but i have the feeling its not the good way to do it.

If someone have a an idea of what i'm doing wrong.

Thanks

1
How about adding :category_id to the list of fields passed to cast?Dogbert
It worked ! The fact is when i've tried to use cast i was using :category as the field key, obviously it tried to cast the association which make no sense. Thanks for your helpClerisse Lucas
@ClerisseLucas please take a time to answer this question, explaining what was wrong and how it was solved. SO is a knowledge base for future users, so it’s mandatory to express the knowledge.Aleksei Matiushkin

1 Answers

1
votes

You don't need to manually do this, just add category_id to the list of allowed fields passed to cast:

|> cast(attrs, [:title, :author, :desc, :content, :content_raw, :logo, :category_id])
                                                                       ^^^^^^^^^^^^