Provide view content in controller

505 Views Asked by At

I have a controller concern which aims at detecting and passing tasks/todos to the view.

In my application layout I have a reserved space to render those tasks

<%= yield(:tasks) if content_for?(:tasks) %>

Here is the module that I include in ApplicationController. It doesn't seem to work properly and the content_for?(:tasks) returns false (byebug says)

module TaskControl
  extend ActiveSupport::Concern

  included do
    before_action :check_tasks

    def check_tasks
      if user_signed_in? and current_user.tasks.todos.any?
        # TODO : better task strategy afterwards
        view_context.provide(:tasks, 
          view_context.cell(:tasks, current_user.tasks.todos.first)
        )
      end
      view_context.content_for?(:tasks) # => false :'(
    end
  end
end

Note that I did check with byebug,

view_context.cell(:tasks, current_user.tasks.todos.first).blank? # => false, so there is something to render
1

There are 1 best solutions below

0
On

Should your controller be responsible for how the view does its job? I would say no.

It makes sense to use a module/concern to DRY up the querying part but not to provide the content for a yield block. Your controller should not have knowledge about how the view is constructed.

Instead you may want to structure your layout like so:

<body>
  <%= yield :tasks %>
  <%= yield %>

  <% if @tasks %>
  <div id="tasks">
  <%= content_for(:tasks) do %>
    <%= render partial: 'tasks' %>
  <% end %>
  </div>
  <% end %>
</body>

This lets the controller set which tasks by providing data - and lets your views alter the presentation by using content_for or provide.

<% # app/views/foo/bar.html.erb %>
<%= provide(:tasks) do %>
  <% # this overrides anything provided by default %>
  <ul>
     <li>Water cat</li>
     <li>Feed plants</li>
  </ul>
<% end %>