Open katbow opened 7 years ago
This had a bit more of a rework. I realised that signup2 would be similar to the :edit resource
that is a 'default' in phoenix, and create2
that followed would be similar to :update
. I modelled the routes & controllers after this.
in router.ex
get "/users/:id/signup2", UserController, :signup2
post "/users/:id/create2", UserController, :create2
and in user_controller.ex
def create(conn, %{"user" => user_params}) do
changeset = User.changeset(%User{}, user_params)
case Repo.insert(changeset) do
{:ok, user} ->
conn
|> redirect(to: "/users/#{user.id}/signup2", action: :signup2, user: user)
{:error, changeset} ->
render(conn, "new.html", changeset: changeset)
end
end
def signup2(conn, %{"id" => id}) do
user = Repo.get!(User, id)
changeset = User.security_question(%User{})
render(conn, "signup2.html", changeset: changeset, action: "/users/#{user.id}/#{:create2}", user: user)
end
def create2(conn, %{"user" => user_params, "id" => id}) do
user = Repo.get!(User, id)
changeset = User.registration_changeset(user, user_params)
case Repo.update(changeset) do
{:ok, user} ->
conn
|> Healthlocker.Auth.login(user)
|> put_flash(:info, "User created successfully.")
|> redirect(to: user_path(conn, :index))
{:error, changeset} ->
render(conn, "signup2.html", changeset: changeset)
end
end
Since signup2 takes an id, I passed it the user (as seems to usually be the case when linking to edit). The part I had the most difficulty with was figuring out what needed to be passed to the action. I modelled this after what the update and edit urls would look like also by inputting the id into the url.
The last problem I need to fix is if the changeset is invalid (for example if password is not the min length), then I get the error I had in the beginning with assign @action not available in eex template.
instead of an error_tag rendering for the password field.
I think the problem lies in here:
def put_pass_hash(changeset) do
case changeset do
%Ecto.Changeset{valid?: true, changes: %{password: pass}} ->
put_change(changeset, :password_hash, Bcrypt.hashpwsalt(pass))
_ ->
changeset
end
end
The changeset that is being returned when the changeset is invalid does not contain an action. I'm not certain at this point what the action needs to be though. Thoughts?
Ok got it now. It wasn't in put_pass_hash
, but in create2
. The render
there also needed the action & user passed along which makes sense since it's rendering the same form as in signup2
!
Actions can also be set in the html.eex instead of passing in @action
. However, since we need the user.id
, it make more sense to grab this in the controller and assign it there.
I have a form with name and email (form1) on one page, which is inserted into the db, then goes to a second form (
/signup2
) to fill in password and security Q&A. The first page was loading as expected and the name & email was being properly inserted into the database upon clicking "Next".However, when it was redirected to
/signup2
there would be an error:So the trouble seemed to be that in
/signup2
there was no action. The create controller that inserted the input from form1 and redirected to/signup2
was as follows when the error was occurring:When the
changeset
was inspected, theaction
was set tonil
.We tried setting this by adding
assign
to the pipe, but assign kept coming back as an undefined function:The solution was to render the
signup2.html
and pass in theaction
directly.