Search code examples
ruby-on-railsrubyviewpartial-viewslocals

Rails 5: partial view with condition and locals


I'm a bit lost in creating "New campaign" button if user has particular role.

In models/roles.rb I have:

class Role < ApplicationRecord
  belongs_to :user, optional: true
  accepts_nested_attributes_for :user

  enum general: { seller: 1, buyer: 2, seller_buyer: 3}, _suffix: true
  enum dashboard: { denied: 0, viewer: 1, editer: 2, creater: 3, deleter: 4}, _suffix: true

In controllers/dashboards_controller.rb I have:

def dashboard_1 
@roles = current_user.roles
  if @roles.any? { |role| role.creater_dashboard? || role.deleter_dashboard? }
    flash.now[:error] = "You are creater/deleter!"
  elsif @roles.any? { |role| role.viewer_dashboard? }
    flash.now[:error] = "You are viewer!"
  else 
    redirect_to users_path
  end
end

I have partial campaigns/_new.html.erb like this:

<li>
<%= link_to new_campaign_path(@campaign), {method: 'get', class: 'btn btn-w-m btn-primary'} do %>New campaign
<% end %>
</li>

and in dashboards/dashboard_1.html.erb I would need to render "New campaign" button if user is "creater" of "deleter" for Dashboard:

<% if ... %>
<%= render partial: "campaigns/new" %>

As I have found out it can be done with locals, however I cannot figure out how? Many thanks for any help!

Added

In layouts/application.html.erb I have this:

<!-- Navigation -->
     <%= render 'layouts/navigation' %>

and in partial _navigation.html.erb I have this:

<li class="<%= is_active_controller('dashboards') %>">
<% if @creator_deleter %>
   <%= link_to dashboard_path do %>
   <i class="fa fa-th-large"></i> <span class="nav-label" data-i18n="nav.dashboard">Dashboard</span>
   <% end %>
<% end %>
 </li>
... #other links to different parts of app

How to hide "dashboard" link in partial if user is not @creator_deleter?


Solution

  • As far as I know you can't render the form with locals from the controller. Is there any reason why you would want to use a local? - these are normally used when rendering partials to pass local variables from one view to the partial, for purposes of reuse. for example...

    <%= render partial: 'form', locals: { my_local_var: my_local_var } %>
    

    I think what you actually want to do is set an instance variable from within the controller that is accessible during the rendering process. For example...

    if @roles.any? { |role| role.creater_dashboard? || role.deleter_dashboard? }
      @creator_deleter = true
    elsif @roles.any? { |role| role.viewer_dashboard? }
        @viewer = true
    else 
      redirect_to users_path
    end
    

    and then you can test for that in your view

    <% if @creator_deleter %>