I hope this is a good place to ask this question about Ecto.
I am using Ecto for database access in my first Phoenix app, and I am in the middle of setting up authentication and I thought creating a table-less model for my login form might be a good way to go.
So I created a module called Alva.Login with a defstruct entry and tried to create a Changeset from it. But Ecto didn’t like that there wasn’t a schema associated with it.
My goal is to use Ecto’s validations/Phoenix.HTML.Form interface. For the time being I am just using my User model for my login form.
Has anybody had experience creating an Ecto schema with all virtual fields without being backed by a table in the database? This example is simple, but in the past I’ve used these “form” objects before in complex forms before stuffing the data into my actual models. This way, my forms can have different validations than the underlying models, and data can be organized differently.
I haven’t actually started learning Phoenix yet so you’ll have to excuse my answer being more general, but are you sure you need a tableless model? For login you could use a Sessions controller and form builders for the form itself?
This is what the create action would look like (again apologies as this is how I would do it in Rails):
def create
user = User.find_by_email(params[:email])
if user && user.authenticate(params[:password])
if params[:remember_me]
cookies.permanent[:auth_token] = user.auth_token
else
cookies[:auth_token] = user.auth_token
end
redirect_to account_root_url, notice: "Successfully signed in!"
else
flash.now.alert = "Email or password is invalid"
render "new"
end
end
Oh yeah, ActiveModel is exactly what I was thinking of. I haven’t seen anything exactly like it for Elixir, but with Phoenix’s Phoenix.HTML.Form module it wouldn’t be too difficult to make a validations layer interface with the form helpers.
The login example was probably too simple since it’s so easy to implement by hand.
I might try my hand at integrating an Elixir validations library with Phoenix’s HTML.Form. Seems like it would be a good first library to build in Elixir.
I’m not actually using Phoenix’s HTML forms, so I am uncertain if it plays by it’s protocol rules. But I can recommend you Vex for creating form objects.
I need to finally upgrade. This looks very good, @josevalim. Thank you for listening to community.
This looks so good, that in fact I would like to see that as stand-alone micro library, extracted from Ecto. My second candidate for similar extraction would be the migration mechanism. What are your thoughts on that? I could have one of our interns (supervised, restarted etc. ;)) having this done as a task this summer.
@caleb it took me a while but I have put together a blog post that may be helpful for you if you haven’t figured out yourself satisfactory ways of doing the above yet:
of course he has. How could I not think about that?
I did a little research project into this direction too, but I basically learned that there is quite a lot code that needs to be first written and then maintained to remain in-line with phoenix_html & ecto. There is even more code needed when you want to support nested schemas or custom types - things Ecto ships with as well.
The other similar library I know of is mentioned above vex, with this adapter for https://github.com/jakub-zawislak/formex_vex for formex library. So if you use formex you can be all set with vex.
The advantage for me, when using Ecto, is that it’s already known and familiar API, and moreover - refactoring is pretty easy. You can first write your stuff in schemas, then refactor by copying over changeset/2 and custom casting/validations to a service module. And you don’t need an additional dependency that will have it’s own quirks (@pragdave’s lib looks young and not complete, it might be very well a research project like mine :)).
I guess Ecto.Repo and Ecto.Query/Ecto.Multi are not strictly necessary, but Ecto.Schema, Ecto.Typo, Ecto.Association (and likely more) are all parts you’d use with changesets.