-
Notifications
You must be signed in to change notification settings - Fork 178
Has Many Relationship Tab
How do you add a has_many tab to manage relationships of a model?
There is a plan to eventually implement a "subresource" feature, allowing easy management of has_many associations, either inline or from a separate form. However here is how you would accomplish it in the mean time.
I'll use an example below of a Project that has_many Tasks. First we'll add the tab and table on the parent resource:
Trestle.resource(:projects) do
form do |project|
tab :project do
text_field :name
text_area :description
end
tab :tasks, badge: project.tasks.size do
table project.tasks, admin: :tasks do
column :description, link: true
column :done, align: :center
column :created_at, align: :center
actions
end
concat admin_link_to("New Task", admin: :tasks, action: :new, params: { project_id: project }, class: "btn btn-success")
end
end
end
The "New Task" link is probably the most complicated bit, but we want to ensure that we pass the project id as a parameter when building the task. To actually use this, we need to override the build_instance
block in the child (Task) resource:
Trestle.resource(:tasks) do
build_instance do |attrs, params|
scope = params[:project_id] ? Project.find(params[:project_id]).tasks : Task
scope.new(attrs)
end
end
This uses the Project association to build the new task if the project id is provided, otherwise it will ignore it and simply to Task.new
. You'll need to make sure that your task form includes a project_id
field somewhere, either via a select tag or hidden_field.
A couple of potential improvements are to load the task form within a dialog (which may or may not make sense for your use case), as well as to show the project select field depending on whether it has been previously set:
form dialog: true do |task|
if task.project
hidden_field :project_id
else
select :project_id, Project.all
end
text_field :description
check_box :done
end
If you want to use scoped resources, prefix the class name with module name and "/":
Trestle.resource(:projects) do
form do |project|
tab :project do
text_field :name
text_area :description
end
tab :tasks, badge: project.tasks.size do
table project.tasks, admin: 'custom_scope/tasks' do
column :description, link: true
column :done, align: :center
column :created_at, align: :center
actions
end
end
end
end