How can I inject custom rendering code into a Cell?

168 Views Asked by At

I've created a Cell that renders a table view of data and I'd like to reuse it for other table views. For each row of that data, I'd like to have some unique elements mixed with the standard columns. Right now, a simplified portion version of my Cell's show.html.slim looks like:

- users.each do |user|
  tr
    / A column unique to User
    td
      = link_to_if current_user == user, "Groups", user_groups_path(user)
    / Common code that can be shared across other tables
    td user.name

I'd like to be able to extract the User-specific code from this level and inject it from above. The Cells documentation states:

If in doubt, encapsulate nested parts of your view into a separate cell. You can use the #cell method in your cell to instantiate a nested cell.

However, it's difficult to simply instantiate a new Cell (edit: within the table cell):

  1. I need to know what cell to create.
  2. I need to be able to pass in information from the parent cell (user in my example).
  3. I need to be able to pass in information specific to the child cell (current_user in my example).

What options exist for injecting this type of partial rendering into a Cell? Are any of them generally preferred solutions?

1

There are 1 best solutions below

0
On BEST ANSWER

I ended up just defining some methods on my cell that accept blocks

class DataTableCell < Cell::ViewModel
  def row_prefix(&blk)
    @_row_prefix = blk
  end

  def render_row_prefix(item)
    return unless @_row_prefix
    @_row_prefix.call(item).call
  end
end

Whenever I want to render the DataTableCell, I provide a block like:

cell = cell(:data_table)
cell.row_prefix do |item|
  cell(:users_row_prefix, user: item, current_user: current_user)
end

Inside my cell, I can just call render_row_prefix(row_item).

I'm not in live with this solutions, as it can be kind of heavyweight, but it does work.