joseratts
Help defining URL Rest structure for nested element
Hello everyone I’m creating an example phoenix app just for learning. My example app is a real estate web portal, so I’m gonna publish places (houses, apartments, etc). I have defined the following entities
Place (house, apartment) 1 → n rooms
So there is a 1 to n relationship between house and rooms and is a composition (so the rooms doesn´t exist if the house doesn’t exist).
My question is, Should be the url structure like following
/houses/house_id/rooms/room_id
If so assuming I have created both entities and liveviews
mix phx.gen.live Places House houses address:string rooms:integer image_path:string
mix phx.gen.live Places Room rooms name:string image:string
and for the last one I created a migration to improve the relationship between houses and rooms
...
create table(:rooms) do
add :name, :string
add :image, :binary
add :house_id, references(:houses, on_delete: :nothing)
timestamps(type: :utc_datetime)
end
create index(:rooms, [:house_id])
end
Are the following router.ex configuration OK? fulfilled the right URL structure ?
#Houses
live "/houses", HouseLive.Index, :index
live "/houses/new", HouseLive.Index, :new
live "/houses/:id/edit", HouseLive.Index, :edit
live "/houses/:id", HouseLive.Show, :show
live "/houses/:id/show/edit", HouseLive.Show, :edit
#Rooms
live "/houses/:house_id/rooms", RoomLive.Index, :index
live "/houses/:house_id/rooms/new", RoomLive.Index, :new
live "/houses/:house_id/rooms/:id/edit", RoomLive.Index, :edit
live "/houses/:house_id/rooms/:id", RoomLive.Show, :show
live "/houses/:house_id/rooms/:id/show/edit", RoomLive.Show, :edit
Any suggestion or comment will be welcome I just keep learning and following in love with the language and the framework. Thanks in advance
First Post!
sodapopcan
This is really a matter of taste though there are at least a couple of things to consider.
If you have breadcrumbs, then having houses/:house_id/rooms/:room_id can certainly be useful. I personally really dislike this structure though. First, if the room were to change to a new house, its URL changes, and second, if I happen to know the id of a room and want to just type the URL in my address bar, I now need to go find its house id as well. Both problems could be solve by having rooms/:id redirect to houses/:house_id/rooms/:room_id, though that’s a little heavy-handed if you don’t strictly need it. And of course if you have a lot of routes where having them both at the top level becomes unmanageable, that’s a different story as well.
Last Post!
sodapopcan
Yes, just remove the underscore. As the warning said, an underscore indicates you will not use the variable. It is a little bit more than a convention since you get warnings, but as you can see _params actually still does bind the variable. On the other hand, a _ by itself actually throws the variable away—trying to reference _ won’t work. But it’s convention to mostly name your throw-away variables so it’s clear what they are.
As far as list_rooms_by_house goes, if you want to list by house_id, you aren’t gaining anything by putting the into a %House{} struct like that. If you want to first ensure the house exists then fetch the house from the database. There are differing opinion here but as you have it, I would just change the function to list_rooms_by_house_id(house_id). You could also fetch the house and preload the rooms.
def get_house_with_rooms(id) do
House
|> Repo.get(id)
|> Repo.preload([:rooms])
What you do heavily depends on how your app works so it’s hard to go over everything. But, for instance, if you have users that can only access certain houses, then putting house_id in a hidden field is a security concern. You would want to first load the house and ensure the user is allow to read/write it (whatever the permissions may be). Then I would have a create_room(house, rooms_attrs) function (whether that lives in a Houses or Rooms context is up to you and a different discussion). Merely putting the house_id in a hidden field would allow a user to change that to whatever id they wanted. If that’s not a security concern then it’s no big deal, but if it is then you definitely shouldn’t do this.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex









