-
Hello! I just want to clarify what's the best way to create a record in a nested route. I didn't find any information in the documentation on this topic, so maybe it's worth to add it to the How-Tos? Anyway, I have two models and a schema (the one for the board does not matter here): class Board < Marten::Model
field :id, :big_int, primary_key: true, auto: true
field :name, :string, max_size: 255
with_timestamp_fields
end
class Column < Marten::Model
field :id, :big_int, primary_key: true, auto: true
field :name, :string, max_size: 255
field :board, :many_to_one, to: Board, related: :columns
with_timestamp_fields
end
class ColumnSchema < Marten::Schema
field :name, :string, max_size: 255
field :board_id, :int # Should this even be here in the schema?
end
I now have following path class Boards::Columns::CreateHandler < Marten::Handlers::RecordCreate
template_name "boards/columns/create.html"
model Column
schema ColumnSchema
before_dispatch :add_board_to_context
def success_url
reverse("boards:detail", pk: params["board_pk"])
end
private def add_board_to_context
# I wanted to just add the board id here, but the id can't be added to the context because uint is not supported.
# I then figured getting the associated model first would be beneficial for data consistency?
context["board"] = Board.all.get!(id: params["board_pk"])
end
end <form...>
<!-- rest of form -->
<input type="hidden" name="{{schema.board_id.id}}" value="{{ board.pk }}">
<!-- rest of form -->
</form> Is there another way? One I also had on my mind was to use the Happy to hear about other solutions. And if this is really not yet in the documentation, it would be worth considering expanding it! |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
Hey! 👋 It really depends on the situation and what you are trying to achieve! I think the solution involving a class Boards::Columns::CreateHandler < Marten::Handlers::Schema
template_name "boards/columns/create.html"
schema ColumnSchema
after_successful_schema_validation :create_column
def success_url
reverse("boards:detail", pk: params["board_pk"])
end
private def create_column
column = Column.new(schema.validated_data)
column.board = Board.all.get!(id: params["board_pk"])
column.save!
end
end Otherwise, if you still want to use class Boards::Columns::CreateHandler < Marten::Handlers::RecordCreate
template_name "boards/columns/create.html"
model Column
schema ColumnSchema
def success_url
reverse("boards:detail", pk: params["board_pk"])
end
def process_valid_schema
column = Column.new(schema.validated_data)
column.board = Board.all.get!(id: params["board_pk"])
column.save!
super
end
end Those are the cleanest solutions I think. Presently, |
Beta Was this translation helpful? Give feedback.
Hey! 👋
It really depends on the situation and what you are trying to achieve!
I think the solution involving a
board_id
schema field would be necessary in situations where the form needs to display a list of boards to select from (with a select input for example). If the board is inferred from the route and can't be selected, then I would opt for a solution that does not involve adding a schema field and that does not involve using a hidden input (since the value of such inputs can technically be overridden by end users). UsingMarten::Handlers::Schema
instead ofMarten::Handlers::RecordCreate
could work in this light: