Interpolated Ruby within a method call? - ruby-on-rails

On my user model, I have a bunch of attributes like is_foos_admin and is_bars_admin that determine which kinds of records a user is allowed to edit.
I'd like to DRY out my edit links, which currently look like this:
<%= link_to 'Edit', edit_foo_path(foo), :class => 'edit' if current_user.is_foos_admin? %>
...
<%= link_to 'Edit', edit_bar_path(bar), :class => 'edit' if current_user.is_bars_admin? %>
I want to make a helper that lets me pass in a foo or bar and get back a link to edit it, like so:
<%= edit_link_for(foo) %>
The helper might look like this (which doesn't work):
def edit_link_for(thing)
if current_user.is_things_admin?
link_to 'Edit', edit_polymorphic_path(thing), :class => 'edit'
end
end
The model-agnostic edit_polymorphic_path method gets me halfway there, but it's the "is_things_admin" method that I don't know how to universalize. If I could use interpolated Ruby inside of a helper, I'd want to do something like
if current_user.is_#{thing.class.name.downcase.pluralize}_admin?
But of course that doesn't work. Any ideas?

Try using send:
if current_user.send("is_#{#model}_admin?")

Related

Can i use variables in Rails link_to method?

Can i use variable for Rails link_to helper for making different link with variables?
For example,
<%= link_to users, users_path %>
I have link like this,
And i'd like to change this url with variable examples
So i changed url like this,
<%= link_to users, "#{examples}_path" %>
This not worked because of whole string change to url.
How can i change my link_to for use this with different variable for DRY codes?
What you're asking is really just how to perform dynamic method calls. In Ruby you can do it with send (and public_send):
<%= link_to users, send("#{examples}_path") %>
The difference between the two is that send will let you violate encapsulation and call private/protected methods.
You can also do it by calling call on the Method object:
<%= link_to users, method("#{examples}_path".to_sym).call %>
However you most likely don't even need this it in the first place. Just use the polymorphic routing helpers to create links from models:
# a link to show whatever resource happens to be
<%= link_to resource.name, resource %>
<%= link_to "Edit", edit_polymorphic_url(resource) %>
<%= link_to "New", new_polymorphic_url(resource_class) %>
<%= link_to "Frobnobize", polymorphic_url(resource, :frobnobize) %>
# a link to the index
<%= link_to resource_class.model_name.plural, resource_class %>
These all use a set of heuristics to figure out what the corresponing path helper is and then call it dynamically with send.
Or if you want to link to a specific controller or action just use the functionality provided by url_for:
# link to a specific controller action
<%= link_to "Baz", { controller: :foo, action: :bar } %>
# Will use the current controller
<%= link_to "Baz", { action: :bar } %>

Rails add dynamic attribute on data content helper link

i need to get a ajax tooltip on a dynamic link, so the logic seems to concatenate it. but, still not work, so, someone know a way to do this?
thank's
<%= link_to "Profile", edit_user_path(current_user), :class =>"ttooltip", :data => {:url => "/users/#{#current_user}/links"} %>
You're string interpolating the current user object, which will call .to_s on the user object, which probably isn't what you want.
If links is nested under each user, you typically follow the 'users/:id/links' so you need to interpolate the id instead of the user object like so:
<%= link_to "Profile", edit_user_path(current_user), :class =>"ttooltip", :data => {:url => "/users/#{current_user.id}/links"} %>
(Where current_user is a helper method that returns the current_user object.)

Rails not routing edit method using /edit

I am using the following code to attempt to link the customer's name to the edit method.
<%= link_to "#{customer.name}", customer, method: :edit %>
But when I click on the name it opens up /customer/1 instead of /customer/1/edit
If I manually enter /customer/1/edit it opens the page correctly. The worst part is that it used to do it correctly and then stopped.
How do I get my edit method to use the /edit again?
Link will be like this..
<%= link_to "#{customer.name}", edit_customer_path(customer) %>
if you want to mention method in link_to, you can do it as,
<%= link_to "#{customer.name}", :controller => 'customers', :action => 'edit' %>

Click pictures and update database row on rails

I need to be able to click an image (out of a bunch of images) and update a profile table based on the image clicked.
List of images in my view:
<% #pages_selection.each do |pages_selection| %>
<img>
<%= link_to image_tag(pages_selection.page_picture, '#') %>
</img>
<% end %>
Then I've got a method in my controller, called save_new_scores_to_profile, that averages the data from the picture and updates the profile values.
How do I call my controller method when my link_to (the image) is clicked? Is there something like this available?
if link_to clicked
perform_controller_or_helper_method
end
Because the user needs to select multiple images, I want them to stay on the page after clicking the images (that's why I have the link directed to '#'. I also have a submit button at the end of the page if that helps.
I'm open to using something other than link_to.
EDIT:
Here's where I'm at now in routes
resources :preferences do
member do
get 'save_new_scores_to_profile'
get 'checked_average_with_profile'
end
end
and the view:
<% #pages_selection.each do |pages_selection| %>
<img>
<%= link_to image_tag(pages_selection.page_picture, :controller =>
:checked_average_with_profile, :action => :save_new_scores_to_profile, :image_id
=> pages_selection.id) %>
</img>
<% end %>
I have functions checked_average_with_profile and save_new_scores_to_profile in my controller that I know work (after testing with helper functions).
link_to image_tag(pages_selection.page_picture, :controller => :my_controller, :action => :save_new_scores_to_profile, :image_id => pages_selection.page_picture.id )
Insted of my_controller put the name of your controller.
With the :image_id you have passed a parameter that you can reference in your controller action with the params hash like: params[:image_id].
Do all your work in that controller action (or with additional calls of helper methods),
find the picture that has that image_id and make a redirect_to #picture_with_that_id

Routing problem with calling a new method without an ID

I'm trying to put together a form_tag that edits several Shift objects. I have the form built properly, and it's passing on the correct parameters. I have verified that the parameters work with updating the objects correctly in the console. However, when I click the submit button, I get the error:
ActiveRecord::RecordNotFound in ShiftsController#update_individual
Couldn't find Shift without an ID
My route for the controller it is calling looks like this looks like this:
map.resources :shifts, :collection => { :update_individual => :put }
The method in ShiftsController is this:
def update_individual
Shift.update(params[:shifts].keys, params[:shifts].values)
flash[:notice] = "Schedule saved"
end
The relevant form parts are these:
<% form_tag( update_individual_shifts_path ) do %>
... (fields for...)
<%= submit_tag "Save" %>
<% end %>
Why is this not working? If I browse to the url: "http://localhost:3000/shifts/update_individual/5" (or any number that corresponds to an existing shift), I get the proper error about having no parameters set, but when I pass parameters without an ID of some sort, it errors out.
How do I make it stop looking for an ID at the end of the URL?
I think that you need to tell the form tag helper you want to use PUT instead of POST
<% form_tag( update_individual_shifts_path, :method => :put) do %>
... fields ....
<%= submit_tag "Save" %>
<% end %>
Amazingly, it turns out that I was able to fix this by a combination of renaming the method and passing a dummy variable. Changes were to the lines:
form.html.erb:
<% form_tag( poop_individual_shifts_path ) do %>
routes.rb:
map.poop_individual_shifts "poop_shifts", :controller => 'shifts', :action => "poop_individual", :method => "put", :id => 4
map.resources :shifts
There I pass it an ID of 4 every time, it doesn't matter, it's not actually doing anything with the shift object it goes and grabs, it's just ... I don't know, a hack, I guess.
shifts_controller.rb:
def poop_individual

Resources