1

I am struggling to check returned enum value. In models/roles.rb I have enums:

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/dashboard_controller.rb I have this:

class DashboardsController < ApplicationController
  def dashboard_1
    @roles = current_user.roles
    Role.select(:dashboard).where(user_id: current_user)
    if
     flash.now[:error] = "You can do whatever want!"
    else 
     flash.now[:error] = "Only view!"
   end
 end

In console I can get this:

Role.select(:dashboard).where(:user_id => 1)
Role Load (0.3ms)  SELECT "roles"."dashboard" FROM "roles" WHERE "roles"."user_id" = ?  [["user_id", 1]]`=> #<ActiveRecord::Relation [#<Role id: nil, dashboard: "deleter">]>` 

where dashboard: "deleter" is my desired outcome. I want to check in controller that if user role for dashboard is "deleter" (flash.now says "You can do whatever want!"

Please, any suggestions how to do this? Many thanks!

UPDATE

This is my controllers/dashboard_controller.rb

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

In dashboard_1.html.erb I try to show "New campaign" button only if user is "deleter" for Dashboard section:

<% if @roles.deleter_dashboard? %>
   <%= link_to new_campaign_path(@campaign), {method: 'get', class: 'btn btn-w-m btn-primary'} do %>New campaign
   <% end %>
<% end %>

However I keep getting this error - undefined method deleter_dashboard? for Role::ActiveRecord_Associations_CollectionProxy How do I make it working right?

matiss
  • 747
  • 15
  • 36

1 Answers1

0

Maybe you could just use the instance variable @roles that you've initialized

if @roles.any? { |role| role.deleter_dashboard? }
  flash.now[:error] = "You can do whatever want!"
else 
  flash.now[:error] = "Only view!"
end

You should be able to role.deleter_dashboard? according to the documentation of Enum

coolcheese
  • 106
  • 7
  • You're welcome. Also - I don't really see the full scope of the functionality that you're trying to implement but I guess you don't have to initialize an instance variable `@roles` for this purpose, use `roles` instead (considering that you are not acessing this information across the controller methods afterwards). – coolcheese Oct 01 '16 at 18:52
  • Thanks for the tip. In ideal world I was thinking to cache all current_user roles at login. `Role.where(:user_id => 1)` finds all roles for 1st user. It is single row with multiple columns (enums in cells) from Roles table. With this info in cache I would check current_user roles when accessing any section of my app. Do you have any idea of how to do this? Any hint would be great. – matiss Oct 02 '16 at 05:25
  • You definitely could cache roles at login althogh I'm not really sure if that's necessary. I don't think there would be much performance gain (if any) with the utilization of roles cache, in the end you have to query the DB at login anyway and I really doubt having one query here and there would hurt your apps performance. Don't try to overcomplicate things, optimize when you need to :). Btw you might want to check [pundit gem](https://github.com/elabs/pundit) for user authorization and maybe even [rolify](https://github.com/RolifyCommunity/rolify) – coolcheese Oct 02 '16 at 14:23
  • Yes, I will not do the cache thing. Not sure if I need Rolify as I can do this role checking query for each section of app. I'm trying to implement Pundit, however something is not working properly. So I am experimenting without Pundit: `<% role.creater_campaigns? or role.deleter_campaigns? %> <%= link_to "New campaign", new_campaign_path(@campaign) %> <% end %>` but I get _expecting end-of-input _ error – matiss Oct 02 '16 at 15:13
  • You are probably missing an `if` in the first ebmedded Ruby conditional and it should look like this `<% if role.creater_campaigns? || role.deleter_campaigns? %>`. I substituted the `or` for `||` as you can see. The `and` or `or` operators are usually used for control flow ([explanation](http://stackoverflow.com/questions/1426826/difference-between-and-and-in-ruby#answer-10648796)) and [some people even discourage you to use it at all](https://github.com/bbatsov/ruby-style-guide#no-and-or-or). – coolcheese Oct 02 '16 at 15:46
  • I'm trying to implement it, however I keep getting error: _undefined local variable or method role_ My code: `
      ` `<% if role.creater_campaigns? || role.deleter_campaigns? %>` `<%= link_to new_campaign_path(@campaign), {method: 'get', class: 'btn btn-w-m btn-primary'} do %>New campaign` `<% end %>` `<% end %>` `
    ` Please, can you check what am I doing wrong?
    – matiss Oct 03 '16 at 18:12
  • I suggest you to read this [post](http://stackoverflow.com/questions/25730570/passing-local-variables-to-a-view-from-controller#answer-39828730) as I would not like to create duplicate posts. You can't expect a local variable to be accessible from view, you've got to initialize an instance variable, in this case `@role`. Initialize it in your controller action method and then use it in it's view (`<% if @role.creater_campaigns? || @role.deleter_campaigns? %>`). Your embedded code could work in [this case](http://stackoverflow.com/questions/6672454/passing-parameters-to-partial-view) though – coolcheese Oct 03 '16 at 22:12
  • Thank you, I read those posts and tried to implement both ways, however it does not work so far. Please, can you check my post update here above? I updated what I have in controller and view and what error do I get. – matiss Oct 04 '16 at 20:03
  • I see that you are struggling with some pretty basic things, I highly advise you to complete [a proper Rails tutorial](https://www.railstutorial.org/). You can not call `deleter_dashboard?` on `@role`, (which should, btw, by the most common conventions, be called `@roles`) because it's and instance of `Role::ActiveRecord_Associations_CollectionProxy`, which is **not** an instance of `class Role` on instance of which could the `deleter_dashboard?` be invoked. Also remove `Role.select(:dashboard).where(user_id: current_user)`, it's completely useless as you are not assigning its result – coolcheese Oct 04 '16 at 22:07
  • Yes, I am working with that tutorial as it is really great. I am trying to follow Harlts suggestion not to use too many gems and try to do as much as possible on my own. To be honest I reverted from `@roles` to `@role` as I have been totaly lost since I got that error. I have replaced with `@roles` and removed `select` line (see my update above), however I keep getting that error. Please, help! – matiss Oct 05 '16 at 04:30