Hide link in rails based on condition - ruby-on-rails

I have an Opportunity and a User model. A User can log in as an admin (I have admin as a boolean attribute). I want users to be able to delete opportunities if and only if they are an admin and I was wondering if anyone had any idea how to do this? So far I have the following delete link for my opportunity:
views/opportunities_opportunity
<%= link_to_if(#user.admin?, "Delete", opportunity, method: :delete, data: {confirm: 'Are you sure?'}) %>
However, I keep getting the error "undefined method `admin?' for nil:NilClass"
Please help. Thanks!!

fixed... I use #current_user.admin? instead and it worked.

Related

Rails 5 Paranoia - How can I 'show' a deleted record?

Upon soft-deleting a record, I'm unable to call it on the show action on the controller, for it looks for a record matching the record's ID WHERE deleted_at IS NULLL, which is correct given the purpose of the gem, but I'd still like to be able to access it on a sort of a "readonly" state, within the application, in order to allow the user to review the archive and possibly restore it.
How can I work around the deletion scope so that I can access the object again?
UPDATE 1
By #slowjack2k's advice, I can access the soft-deleted records with the following query:
#area = Area.only_deleted.find(params[:id])
A new problem arose afterwards, due to CanCanCan's load_and_authorize_resource: it attempts to call
#area = Area.find(params[:id])
ignoring the only_deleted filter, resulting in error since the selected id is only found where deleted_at is not null (not deleted), and disabling the authorization "fixes" it, so it must be an issue between CanCanCan and Paranoia.
Here's a thread with the exact same issue: https://github.com/rubysherpas/paranoia/issues/356
Here's the new issue thread on StackOverflow: Rails 5 compatibility between Paranoia and CanCanCan, compromised?
I'll update it again with the solution if I find one, thank you.
UPDATE 2
The issue was solved and the solution can be found on the new issue thread I've mentioned above.
You can use YourModel.readonly.find_with_deleted(params[:id]) or YourModel.readonly.with_deleted.find(params[:id])
I've been throw this before and I'll explain my approach to solve this..
Overview:
Giving that I have a Model Called Items, I'll have a page that will display all Soft Deleted Items I'll call the inactive. Using the same template of index action
First you should create a route
resources :items
collection do
get 'inactive'
end
end
Second you should create a controller action...
def inactive
#Items = Items.only_deleted
render action: :index
end
Third, I'll go to ../items/inactive And it'll display the in active or archived Items
You may also after that use...
<%= link_to "Archived Items", inactive_items_path %>
In your views to go to that page
Update
Here I should mention that using the index view to render the inactive Items collection may leave you with broken links.
views/items/index.html.erb
<td><%= link_to 'Show', merchant %></td>
<td><%= link_to 'Edit', edit_merchant_path(merchant) %></td>
<td><%= link_to 'Destroy', merchant, method: :delete, data: { confirm: 'Are you sure?' } %></td>
So that leave you with a choice to make, Whether you choose to group the edit links for the normal Items and put it in a partial then group the inactive links and put it in another partial, Then to render the partial depending on which action is rendering the view.
Or Option #2 is to lose the render action: :index line and make a separate view inactive.html.erb with its links and save your self the headache. Although it would be against the DRY principal.

Confirm boxes not working for delete links only

I am currently banging my head against the desk trying to figure out why this is not working. I am trying to get the ujs confirmation box to show up when a delete link is clicked. Currently, the item is deleted with no confirmation box. Here is my delete link:
<%= link_to "void", project, method: :delete, data: {comfirm: "Are you sure you want to delete this project?"} %>
Here is where it gets strange. The following link (not a delete link) works as expected:
<%= link_to "About", about_path, data: {confirm: "test test"} %>
I did some digging in the gem itself and was able to discover that, with the delete link, the data-message attribute is not being parsed correctly in the following code. Specifically, the
if (!message) { return true; }
is returning true, where message is defined as follows:
message = element.data('confirm')
Note: element is the entire link itself. Can anyone help me find out why this is happening? I am using Rails 3.2 if it helps.
I have done this, just make it confirm instead of comfirm, and it works fine.
<%= link_to "void", project,method: :delete, data: {confirm: "Are you sure you want to delete this project?"} %>

How to make confirm message i18n compatible

I'm relatively new to Rails, and have been programming a few months.
I'm trying to use the t() method for internationalization, but it doesn't seem to work when I ask for confirmation in a link_to.
For example, when I write
<%= link_to t( ".delete_student_info"),
#student,
method: :delete,
confirm: "child_deletion_confirmation"
%>
...I predictably get a link_to that works and asks the confirmation question
However, when I write
<%= link_to t( ".delete_student_info"),
#student,
method: :delete,
confirm: t( ".child_deletion_confirmation")
%>
...I get the following output
Child Deletion Confirmation" data-method="delete" href="/en/student_profiles/41" rel="nofollow">Delete Student Info
Is there something conceptual that I am missing? I've looked in the Rails Guides Rails i18n API, but it doesn't address this issue. I'm thinking that maybe the confirm: is something different, but I don't know how to look it up. Any ideas?
I tried this out on my Rails 4 console and it worked fine:
helper.link_to "Visit Other Site", "http://www.rubyonrails.org/", data: { confirm: I18n.t("date.formats.default") }
# => "<a data-confirm=\"%Y-%m-%d\" href=\"http://www.rubyonrails.org/\">Visit Other Site</a>"`.
Now, note the behavior when using nil for the :confirm is like what you're seeing:
helper.link_to "Visit Other Site", "http://www.rubyonrails.org/", data: { confirm: nil }
# => "Visit Other Site"
So this makes me think that somehow your translation is evaluating to nil. However, I can't seem to figure out how to duplicate that issue...
I'll expand this answer to try to help more if you can show what the translations file looks like?

Abstract the delete link for a polymorphic model used in a nested controller

Question
In a polymorphic model, thats used in nested controllers, how can I abstract my delete link's path so I'm not hardcoding upload_permitted_user_path(#permissible, permitted_user)?
Details
I have a polymorphic model called permitted users. Basically theres a bunch of objects in my application where we need to control who can see it. So a post, photo, etc can have permitted users.
I want to be able to delete permitted users on the post#edit, photo#edit, etc pages.
I have this line:
# Used in "posts#edit"
<%= link_to 'Delete',
post_permitted_user_path(#permissible, permitted_user), # This should not be hardcoded.
method: :delete,
data: { confirm: 'Are you sure?' } %>
# Used in "photos#edit"
<%= link_to 'Delete',
photo_permitted_user_path(#permissible, permitted_user), # This should not be hardcoded.
method: :delete,
data: { confirm: 'Are you sure?' } %>
How can I abstract the path so I'm not hardcoding <MY_TOP_LEVEL_CLASS>_permitted_user_path(#permissible, permitted_user)?
Found the answer (feel free to repost and I'll accept :P)
Creating polymorphic links is easy using "polymorphic routes".
You can easily generate the proper link using polymorphic_url([#top_resource, #next_level_resource]) in any view.
For example:
polymorphic_url([:admin, #article, #comment]) becomes admin_article_comment_url(#article, #comment).
Another example without the leading :admin:
polymorphic_url([#article, #comment]) becomes article_comment_url(#article, #comment).

How to setup delete selected messages feature in ruby on rails

I'm about to finish the final part of my thread messaging system for users. All deletion works great however before I move on to my next feature I'd like to give users the ability to delete selected messages.
Here's a way I've thought of doing it so far.
Add a check box tag to the each loop that loops through each message.
Have a "delete selected" link that goes to my messages controller "destroy_selected_messages" action.
What I need to do is some how grab an array of all the selected messages id's. Then pass it to the path as an argument. The delete all links path.
<%= link_to 'Delete Selected', messages_destroy_selected_messages_path(ARRAY_WITH_IDS), :method => :delete, :confirm => "Are you sure?" if #current_thread_messages.any? %>
This delete selected link won't be part of the loop because I don't want it showing for every message but at the top of the thread instead.
I need to figure out how to pass the array with all the selected messages ideas into that argument. How do I get them from the each loop without going into my messages helper and writing some funky method.?
I have the checkbox tag e.g. check_box_tag ... how do I setup an empty array and then so I can pass in the messages id? e.g.:
<%= check_box_tag ......., :value => message.id &>
Help would be appreciated. I looked at an old screencast in railscasts but it's from 2007 I think.
Kind regards
You can make name="message_ids[]" for multi select inputs. It will get passed as an array through HTTP server to your params[:message_ids].
From the HTML side of the problem, I think that form helper <%= check_box_tag "message_ids[]", :value => message.id %> should suffice.
In the controller action, log the params[:message_ids] and look it up, it should be an Array.

Resources