Show and hide based on user role in rails - ruby-on-rails

I have the following code in my home.html.erb file;
<!-- if seeker is logged in show button "Grab it" -->
<% if user_signed_in? %>
<div class="grabit alignright">
<small>want to work on this?</small>
<!-- if seeker is not logged in, show him the output text of "Sign in to work on this job" -->
<% else %>
<small>are you a guru? want to work on this? Sign up.</small>
<% end %>
</div>
Now as you can see I'm trying to have Seeker as a user role. Depending if that type of user with that type of role is signed in or not, different content is shown.
I have Devise + CanCan installed. Now very new to this and I've looked all over to see how to do this. I will have "Users" with normal roles of users and "Seekers" with seeker role. Using the above code only shows when a user is signed in, but not a seeker.
Is it as simple as seekers_signed_in? that I should be using? compare to user_signed_in? I've generated the Devise views for both Users and Seekers and Admins. Admins will be able to delete, update, etc. for users and seekers. Users post items and Seekers grab them.
Can anyone help?

You don't have to create Users& Seekers (two devise models), instead you can create only one model as common and call it User, then add as many roles as you need.
I recommend using this gem for easy roles configuration,
Then in your home.html.erb you simply do the following:
<!-- if seeker is logged in show button "Grab it" -->
<% if user_signed_in? && current_user.is_seeker? %>
<div class="grabit alignright">
<small>want to work on this?</small>
<!-- if seeker is not logged in, show him the output text of "Sign in to work on this job" -->
<% else if !user_signed_in?%>
<small>are you a guru? want to work on this? Sign up.</small>
<% else%>
<small>You are not a seeker, you need to be a seeker!</small>
<% end %>
</div>
CanCan is used at Controller level, so the above approach is easy and direct for your case.
I hope this will help.

Related

Allowing An Admin to Assign User's To A Sub-admin in Ruby on Rails

I'm creating a bloglike application which includes features based around different tiers of admins.
I have a main admin who I want to give the ability to turn a user into a subadmin, which will be a type of admin who has access to some admin features but not all.
Currently I have this _users partial which I use in a view to display all users to the admin:
<li>
<%= link_to user.name, user %>
| <%= pluralize(user.how_many_new_posts?, "unsubmitted daily post") %>
<% if current_user.admin? && !current_user?(user) %>
| <%= link_to "delete account", user, method: :delete,
data: { confirm: "You sure?" } %>
<% end %>
</li>
This will render the name of each user, how many unsubmitted posts they have, and the option to delete the user.
I want to include another option here, a way of clicking a button to make the specified user a subadmin. Once this button is clicked it should give the admin the ability to assign other users to this subadmin, so that they can monitor them in the same way as the above partial. I assume this will require some new kind of partial, but I'm not totally sure how it would work. Does anyone have any experience with this?
You will need to create a model say Role which has_many users and User belongs_to Role or whatever relationship you prefer.
You may have difderent roles in there..
You can then manage there accessibilities/abilities based on their role designing your own or there are gems at your disposal e.g. cancancan
Then, in your view you can provide a dropdown list for available roles and change the role_id on submit.

Capybara and Cucumber cannot find checkboxes even with unique ID

I have been encountering a problem when running cucumber to test the functionality of some of my checkboxes. The checkboxes are located on the edit profile page for users and allow users to check off their interests. However, every time I run cucumber it says that it is unable to find the checkbox. But this does not happen for all of the checkboxes on the page, only the checkboxes for the interests. Originally we thought that it was because the checkboxes did not have unique IDs, but now we have updated the checkboxes to have unique ids and they still cannot be found by capybara and cucumber.
The view code looks like this:
<% #interests.each do |interest| %>
<div class="form-group">
<%= label_tag 'interests', interest.name, class: 'col-sm-2 control-label' %>
<div class="col-sm-6">
<%= check_box_tag 'interests[]', interest.id, resource.interest_ids.include?(interest.id), {class: 'form-control', id: "interest_#{interest.id}"} %>
</div>
</div>
<% end %>
The step definition is:
When /^(?:|I )check "([^"]*)"$/ do |field|
check(field)
end
The feature look like this:
Feature: Edit Profile as a User
As a BoardBank User
So I can keep my info up to date
I want to be able to edit my profile
Background:
Given I login as a User
And I am on the home page
Scenario: Edit profile
When I follow "Profile"
And I follow "Edit Profile"
And I fill in "user_firstname" with "User"
And I fill in "user_lastname" with "Joe"
And I fill in "user_address" with "123 userville"
And I fill in "user_city" with "Userton"
And I select "Alabama" from "user_state"
And I fill in "user_zipcode" with "90210"
And I fill in "user_phonenumber" with "555-555-5555"
And I select "Bachelors" from "user_education"
And I fill in "user_areaofstudy" with "Magic"
And I check "interest_2"
And I check "user_previous_experience"
And I fill in "user_current_password" with "password"
And I press "Update"
Then I should see "Your account has been updated successfully."
And I should be on the homepage
When I run cucumber this is what happens:
And I check "interest_2" #features/step_definitions/web_steps.rb:89
Unable to find checkbox "interest_2" (Capybara::ElementNotFound)
./features/step_definitions/web_steps.rb:90:in `/^(?:|I )check "([^"]*)"$/'
features/edit_profile.feature:23:in `And I check "interest_2"'
We think that it must be an issue with the view code and how the checkboxes are appearing on the page, but we could not find any solution to this issue when searching.
Try the find the checkboxes in this way:
within('.form-group') do
page.find('input[type=checkbox]').set(true)
end
If you use chrome, you can inspect the element and copy the css or xpath. That helps me a lot. Also, if you use the pry gem, I sometimes set js: true on capybara, so I can see what's going on in the browser, then walk through step by step until I get what I want. For me, it's way easier to do it that way.

Custom Button Action in Rails View - Ruby on Rails

Rails newbie here. I have an array of hashes that contain Facebook Friends that I'd like to optionally turn into 'Contacts'. I have an index view that lists all of the users's 'friends'. I'd like to have a custom button that enables the user to turn each friend into a contact. How do I do this in Rails?
Index view - I am currently listing each user with their avatar & name. I'd like to add the button in each list item.
Note: I do not have a Friend model, as I am simply pulling this data in from the Facebook Graph API as an array of hashes.
<% #friends.each do |friend|%>
<li> <%= image_tag(fb_avatar(friend["id"], "type=square"))%> <%=friend["name"]%> #put button here </li>
<% end %>
Custom make_friend_contact method in Application Helper (to be called on a friend):
def make_friend_contact
Contact.new(name: self["name"], uid: self["id"], avatar_url: fb_avatar(self["id"], "type=square"), user_id: params[:user])
end
Any help is much appreciated. I've done quite a bit of reading, and I can't seem to crack this one. Thanks!
One solution might be to use button_to. You can check it out in the Rails API. Here is one of their examples:
<%= button_to [:make_happy, #user] do %>
Make happy <strong><%= #user.name %></strong>
<% end %>
# => "<form method="post" action="/users/1/make_happy" class="button_to">
# <div>
# <button type="submit">
# Make happy <strong><%= #user.name %></strong>
# </button>
# </div>
# </form>"
where the button calls the make_happy action in the Users controller on #user.
You could do something similar by making an action in your Users controller that creates a new Contact, using a friend parameter.
def make_friend_contact
friend = params[:friend]
Contact.new(name: friend["name"]...
end
Then you just have to send the friend parameter with the button's POST request.

Dropdown to view a page as different user roles while admin

I currently have a view simplified below...
<% if can? :manage, #task %>
Admin
<% elsif can? :update, #task %>
Moderator
<% elsif current_user %>
User
<% else %>
Not logged in
<% end %>
This view has a large number of fields that are wrapped in similar conditionals for each user and I currently have to log in and out of test accounts to check formatting.
I want to be logged in as an admin but have a dropdown to select whether the page is rendered as Admin or Moderator or User or Not logged in
I have some rough ideas of solutioning, but don't know which to follow...
Bake into cancan with an extra column on user that I can set from a navbar dropdown form
Create user specific methods
Allow a url parameter to request session view and render accordingly
Is there a best practice around this?
How about if you implemented something like the real/effective user dichotomy of Unix?
You're existing infrastructure is the 'real' user based on whatever authentication has occurred but you also associate an 'effective user' with each session.
The effective user starts out the same as the real user but can be changed to something else. Changing the effective user should be conditioned on the real user having admin rights.
Condition all your layout on the effective user and not on the real user.
Condition your 'change effective user' drop down on the real user.

Making Multi-user Contact Manager with Rails, devise and MongoDB

I'm working on simple contact manager that supports multi-user. I'm using with Rails, Device, and MongoDB with MongoID.
With devise, I easily attached basic login functionality with devise, and used embedded_in for attaching contact model to user model.
However, I can't make user's dashboard page(and RESTful API endpoint) that displays user's contact list. I should make every users' contact list private to each user.
EDIT : I followed RailsApp tutorial, and this is what I've done so far. I have index page that displays every users' list, and detail view for adding contact data.
The problem is, when user sign up, every user can see everyone's contact. I want to restrict every user should only see their contact list.
And one more thing, I want to unify API endpoint for every user like:
http://domain.tld/contact.json for logged in user's contact.
Devise will give you this helper current_user. So you can do this in your controller.
# dashboard_controller.rb
before_filter :authenticate_user!
def index
#contacts = current_user.contacts
end
Then in your view
# dashboard/index.html.erb
<% #contacts.each do |contact| %>
<p>
<strong><%= contact.name %></strong> <br />
Phone: <%= contact.phone %>
Mobile: <%= contact.mobile %>
Email: <%= contact.email %>
</p>
<% end %>
Is that what you're after?

Resources