How to override function new so I can send parameter - ruby-on-rails

I have model Product with has_may :benefits, now in link_to for new benefit I don't know how to send ID of product so I can go with
Product.find(params[:id]).benefits.new(...)
Normal new method is
<%= link_to t('add_new_benefit'), new_admin_benefit_path %>
I want to send #product object so I can get id from it.
I wanna send it like this
<%= link_to t('add_new_benefit'), new_admin_benefit_path(#product) %>
routes.rb
...
namespace :admin do
root "action_logs#index"
get "toolkit", to: "toolkit#index"
resources :admins
resources :products
...
resources :benefits
end

I believe you just want to pass id as a param. Eg:
<%= link_to t('add_new_benefit'), new_admin_benefit_path(product_id: #product.id) %>
Many examples here

Related

Rails has_many through association delete path

I have a place model and a user model and a user_place model, user_place belongs to user and place both. Traditional has_many through association.
I have a page where you can view the users associated with a place. My routes look like:
resources :places do
resources :user_places
end
which generates these routes:
place_user_places GET /places/:place_id/user_places(.:format) user_places#index
POST /places/:place_id/user_places(.:format) user_places#create
new_place_user_place GET /places/:place_id/user_places/new(.:format) user_places#new
edit_place_user_place GET /places/:place_id/user_places/:id/edit(.:format) user_places#edit
place_user_place GET /places/:place_id/user_places/:id(.:format) user_places#show
PATCH /places/:place_id/user_places/:id(.:format) user_places#update
PUT /places/:place_id/user_places/:id(.:format) user_places#update
DELETE /places/:place_id/user_places/:id(.:format)
I don't love this but I'm ok with it for now.
But whenever I try to delete a user_place I have all sorts of issues.
<%= link_to "delete", place_user_place_url(place_id: #user_place.place_id, id: #user_place.id), method: 'delete' %>
No route matches {:action=>"show", :controller=>"user_places", :id=>nil, :place_id=>2}, possible unmatched constraints: [:id]
I had this working previously with slightly different routes and an actual form:
resources :places do
resources :user_places, as: 'user', only: %i[index create new]
delete 'remove_user', to: 'user_places#remove_user'
end
<% if user != current_user %>
<%= form_with model: #user_place, url: place_remove_user_path(#place.id), method: 'delete' do |form| %>
<%= form.hidden_field :user_id, value: user.id %>
<%= form.hidden_field :place_id, value: #place.id %>
<%= form.submit "delete" %>
<% end %>
<% end %>
But this feels hacky, I don't think I should need a specific form, and this was leading the form to be submitted with javascript which I don't want.
What might be a solution is to use shallow nesting in the routes (shallow: true).
resources :places do
resources :user_places, shallow: true
end
Make sure to run rails routes again. The delete method of a user_place will no longer be nested.
You can then simply delete the user_place passing a single variable (an instance of a user place, #user_place). There is no need to set the id (place_id or id) as Rails is smart enough to handle that. Just passing an instance variable is enough for the delete method to find the corresponding record.
<%= link_to "delete", user_place_url(#user_place), method: 'delete' %>

How to search all nested resources without the parent resource?

My app's got Listings nested within Categories.
I can search all the listings when I'm in a particular category with this form:
<%= form_tag category_listings_path(#category), method: :get do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag 'Search', name: nil %>
</p>
<% end %>
As you can see, I must make a get request to the category_listings_path and pass in the current Category.
However, this method fails when I want to put the search bar on a page where no Category exists!
How can I search for all Listings without needing to pass in a Category?
Based on what you wrote, I'm guessing your routes look something like:
resources :categories do
resources :listings
end
This means that all of your routes for listings require a category id. If you want a path for all listings, regardless of category, add:
resources :listings, only: [:index]
to your routes. Then you can have a form that searches to listings_path (which is the path that above route creates) and you don't need a category id.

How to use ruby on rails named routes

I defined nested resources like this
resources :item, :only => [:create, :destroy, :update] do
resources :item_image, :only => [ :new, :create, :show , :destroy, :index]
end
And my routes look like this (output of rake routes)
item_item_image_index GET /item/:item_id/item_image(.:format) item_image#index
POST /item/:item_id/item_image(.:format) item_image#create
new_item_item_image GET /item/:item_id/item_image/new(.:format) item_image#new
item_item_image GET /item/:item_id/item_image/:id(.:format) item_image#show
DELETE /item/:item_id/item_image/:id(.:format) item_image#destroy
I thought the first column of the output is "the named routes".
I want to show a path to /item/:item_id/item_image(.:format) in one of my view.
item_item_image_index GET /item/:item_id/item_image(.:format) item_image#index
I tried this:
<%= link_to "users", item_item_image_index %>
and also this
<%= link_to "users", item_images_path %>
Neither works
I got "undefined local variable or method `item_images_path/item_item_image_index'" error
you should try:
<%= link_to "users", item_item_image_index_url(#item) %>
or
<%= link_to "users", item_item_images_url(#item) %>
or
<%= link_to "users", item_item_image_index_path(#item) %>
or
<%= link_to "users", item_item_images_path(#item) %>
don't forget the url needs an :item_id, hence you need to pass an item as an argument.
actually, you should avoid naming that model "ItemImage". An Item has Images, that's what you need to know. you'll get better helper names like "item_images_url"
item_item_image_index GET /item/:item_id/item_image(.:format) item_image#index
In this route item_item_image_index, you need a item_id in the url
Lets you have an object of Item model named as #item, then your link will be
<%= link_to 'users', item_item_image_index_path(#item) %>
Here You need to append '_path' after the route helper "item_item_image_index". While passing the #item variable, it will take the #item.id as item_id and completes the URL of the link.

Route to controller action

I created an form_tag form:
<%= form_tag(set_image_dokumente_path) do %>
<%= text_field_tag :shit,'', data: {autocomplete_source: search2_patients_path}, :class => "shit" %>
<% end %>
I try to route to set_image action of dokumente controller, but i get the error:
undefined local variable or method `set_image_dokumente_path' for #<#<Class:0x711ff60>:0x762d578>
By default my form_tag goes to dokumente controller index action!
My routes:
resources :images
get "dokumente/index"
post "dokumente/index"
match 'patients/list' => 'patients#list'
resources :patients do
collection do
get :search2
end
end
How do i have to change it?
You can add the as: parameter to you route in order to create a named path.
For example:
post "dokumente/index", as: 'set_image_dokumente'
or similar, I'm not sure what you are trying to achieve, but I hope you get the idea :)
More info:
http://guides.rubyonrails.org/routing.html#generating-paths-and-urls-from-code

How to link to users/id/microposts in Ruby on Rails?

I need create a link to users/id/microposts where id is the user id. I was wondering how I could do that with link_to?
The HTML code is I am using for the moment is :
<strong>Microposts</strong> <%= user.microposts.count %>
Which renders the following :
Microposts
In routes.rb, you should have something like this:
match '/users/:id/microposts' => 'microposts#index_by_user', :as => :microposts_by_user
and in view, you can do like this:
<%= link_to "Microposts", microposts_by_user_path( #user) %>
Assuming that you have your routes setup correctly, that would be a nested route for the microposts, In rails 3 it would be
resources :users do
resources :microposts
end
Then in your view, with link_to you can
<%= link_to "Microposts", user_microposts_path(user) %>
This might be current_user, #user ... whatever user object you want the microposts, it might be from
#users.each do |user|
<%= link_to "Microposts", user_microposts_path(user) %>
end
OR
<%= link_to "Microposts", user_microposts_path(current_user) %>
EDIT: Added in the user object I forgot to passin and some examples with it.

Resources