Rails 3 - how with declarative_authorization test, if user is admin? - ruby-on-rails-3

In the documentation I found this part:
<% permitted_to? :create, :employees do %>
<%= link_to 'New', new_employee_path %>
<% end %>
This is good, but I need to test, if the current user is admin, and if does, so then display some text... Something like
if admin?
I can get this information from associations, like:
if current_user.role == 0
but this is a bit dirty solution... support Declarative Authorization some cleaner and nicer way to do it?

This is what I have been looking for:
if has_role?(:admin)
...
end

Related

Error using nested_form gem with empty association

In my rails app, I have two models, a ClientPage and a ContentSection, where ClientPage has_many :content_sections. I'm using the nested_form gem to both models to be edited with the same form. This works fine as long as the ClientPage has at least one ContentSection, but if there are no associated ClientSections, the using nested_form's link_to_add method throws the following NoMethodError:
undefined method `values_at' for nil:NilClass
The form is structured as follows:
<%= nested_form_for page, form_options do |f| %>
# ClientPage fields
# ClientSections
<%= f.link_to_add "Add new section", :content_sections %>
<% end %>
As long as there is at least one ClientSection associated with the page, this works fine. As soon as there isn't, the error is thrown. Removing the link_to_add also stops the error from being thrown. (There's actually a second nested model under ContentSection, and the same issue arises if there are no associated models.)
Not sure what I'm fairly obvious thing I'm missing, but any pointers or suggestions would be greatly appreciated.
Finally worked this out -- the error was due to the fact that I was using the gem in a slightly non-standard way. Within the form, instead of rendering all of the content sections the standard way:
<%= f.fields_for :content_sections do |section_form| %>
# section fields
<% end %>
I put it inside a loop, as I needed the index of each item (which is not stored within the model itself):
<% page.content_sections.each_with_index do |section, index| %>
<%= f.fields_for :content_sections, section do |section_form| %>
# section fields
<% end %>
<% end %>
The issue doing it this way is that the fields_for method does not get called if the association is empty, and as such the gem cannot build the blueprint for the object (which is used to add in the extra item when link_to_add is called).
The solution was to make sure fields_for got called even if the association was empty:
<% if page.content_sections.empty? %>
<%= f.fields_for :content_sections do |section_form| %>
# section fields
<% end %>
<% end %>

Rails List record and count for each

I have a model called Note. Each note belongs_to :call_reason. And call_reason has_many :notes.
What I want to do in a view is display a list of call_reasons and a total count of each next to it so we can see what the most popular call reasons are.
Here's what I have so far:
dashboard_controller:
def index
#notes = Note.all
end
dashboard view:
<% #notes.each do |n| %>
<%= n.call_reason.reason %>
<% end %>
This lists all notes' call_reasons.
I'm stumbling on how to list each call_reason once with a total count next to it. What I have now just lists all the call_reasons per note which is a mess. I think I could scope this out somehow or change the instance variable but I'm having a hard time getting it right.
Any thoughts?
Since you want to list call reasons, you should start with that:
def index
#call_reasons = CallReason.all
end
Then in your view you can do this:
<% #call_reasons.each do |call_reason| %>
<%= call_reason.reason %> <%= call_reason.notes.count %>
<% end %>
Note that this will perform a query for every call reason in your database. To prevent this you can use a counter cache. Check out the section on counter cache on Rails Guides too.

Rails cache not updating properly

I am using the cache-digests gem and following the instructions as per the Railscast, it creates and reads from a cache as you would expect, but the cache does not seem to be updating properly in relation to an associated record.
When moving a listing from one category to another, the category.live_entries count stays the same for the category I move it from, but goes up for the one I move it to.
So it sounds like I need a touch: all type method so it touches the one I am moving it from as well as the one it is moving to?
_category.html.erb
<% cache category do %>
<li>
<%= link_to category.name, category %>
<% if category.live_entries > 0 %>
(<%= category.live_entries %>)
<% end %>
- <%= category.desc %>
</li>
<% end %>
category.rb
class Category < ActiveRecord::Base
has_many :listings
def live_entries
listings.where(verified: true).count
end
end
listing.rb
class Listing < ActiveRecord::Base
belongs_to :category, touch: true
Any ideas on how to tackle this?
Guess I could create a before_update callback to touch the old category - but is there a better way?
Ok just adding this as an answer - but if anyone has a better solution please feel free to share.
I just added an after_update to touch the old category:
def touch_old_category(listing)
cat = listing.category_id_was
Category.find(cat).touch if cat
end

How do I join and display first_name with last_name?

I am using devise and cancan with rails 3.2.1 and I'm having an unusual problem that I know can be refactored and simplified, but after much searching, I'm stuck.
I have first_name and last_name fields in the user model and have successfully displayed the full name of the user in the users/show.html.erb view using this code:
<%= #user.first_name + " " + #user.last_name %>
And I was successfully displaying a link to the user's show page in the header using:
<% if user_signed_in? %>
<li><%= link_to #user.first_name + " " + #user.last_name, current_user %></li>
<% end %>
But, and I can't figure this one out, after working on another part of the app, the header started giving me an undefined method error message...
In any case, I know there is a much better way to define and work with user names and I have tried some things out, such as adding a name method to the user model, but as you can clearly tell from this post, I am a beginner and have not been able to make that work.
Please let me know if you have any ideas on how to best work with users names in an application like this.
Where are you defining #user? I'm willing to bet that it's in your UsersController show action, which means it's defined for your header in that action only.
Try replacing your header code with this:
<% if user_signed_in? %>
<li><%= link_to current_user.first_name + " " + current_user.last_name, current_user %></li>
<% end %>
The trick is that Devise makes current_user always available when the user is signed in. You don't have to worry about setting a #user instance variable.

Pull friends uid using fb_graph

does anyone know how to pull a list of facebook friends uid using fb_graph? My current code is below but it does not work. I'm using devise and omniauth.
In my user controller
def profile
profile ||= FbGraph::User.me(self.authentications.find_by_provider('facebook').token).fetch
end
In my view
<% current_user.profile.friends.each do |friend| %>
<%= friend.uid %>
<% end %>
I've been looking for solution for days but still in vain and will appreciate if anyone could tell me the clue.
Use friend.identifier instead of friend.uid.