Unable to add custom routes in rails - ruby-on-rails

I am using the mailboxer gem in my rails app to handle private messages between users. I have a separate page to view your inbox and a separate page to view your trash folder. The URL localhost/conversations succesfully loaded the inbox. I want to have a link that can load a separate page for trash, such as localhost/conversations/trashbin. However, I can't get Rails to recognize any routes I create for such a page.
In addition, going directly to that URL displays and error:
Couldn't find Conversation with id=trashbin
I understand why the error is occurring but I don't know how to fix it. The issue is with my routes file:
resources :conversations do
member do
post :reply
post :trash
post :untrash
get 'trashbin', :action => 'trashbin'
end
end
Using resources is causing the app to look for a specific conversation. This is useful throughout the rest of the application except for this one case. I simply want to collect all of the messages that were marked as trash. How can I edit this routes file to accomplish this?
Here are the links I have on the index conversations page:
<%= #conversations.count %> Inbox | <%= #trash.count %> Trash
Thanks!
EDIT:
Thanks to the answers below I have updated the routes to:
resources :conversations do
member do
post :reply
post :trash
post :untrash
end
collection do
get :trashbin
end
end
However, the URL conversations/trashbin now displays an Unknown action error:
The action 'trashbin' could not be found for ConversationsController
My ConversationsController clearly has the action defined. Why is this error appearing?

Don't use a member route - use a collection route instead:
resources :conversations do
member do
post :reply
post :trash
post :untrash
end
collection do
get :trashbin
end
end
See here for more info on this.

Put the route in a collection scope
resources :conversations do
member do
post :reply
post :trash
post :untrash
end
collection do
get :trashbin
end
end

Related

rails: custom route not working

I am trying to create a custom route in my rails app. It should be a variant of the New Record Form generated by a scaffold. I am trying to add new_task(a type of activity in my app).
However, when I navigate to the link I get the following error
ActiveRecord::RecordNotFound in ActivitiesController#show
Couldn't find Activity with 'id'=new_task
# Use callbacks to share common setup or constraints between actions.
def set_activity
#activity = Activity.find(params[:id])
end
def set_customer
My Route File
resources :customers do
resources :contacts, :assets, :activities
get 'activities/new_task', to: 'activities#new', as: :new_task
end
My Rake Routes Output
customer_activities GET /customers/:customer_id/activities(.:format) activities#index
POST /customers/:customer_id/activities(.:format) activities#create
new_customer_activity GET /customers/:customer_id/activities/new(.:format) activities#new
edit_customer_activity GET /customers/:customer_id/activities/:id/edit(.:format) activities#edit
customer_activity GET /customers/:customer_id/activities/:id(.:format) activities#show
PATCH /customers/:customer_id/activities/:id(.:format) activities#update
PUT /customers/:customer_id/activities/:id(.:format) activities#update
DELETE /customers/:customer_id/activities/:id(.:format) activities#destroy
customer_new_task GET /customers/:customer_id/activities/new_task(.:format) activities#new
customers GET /customers(.:format) customers#index
POST /customers(.:format) customers#create
I was trying to use the existing controller's New method, however it seems to want to receive an input of parameter. What I am doing wrong?
You have to define your route as collection route not a member route.
resources :customers do
resources :contacts, :assets
resources :activities do
collection do
get :new_task
end
end
end

Rails ignores collection route and routes to show action instead

I have the following routes:
resources :transactions do
collection do
post :detail
end
end
When I got to http://localhost:3000/transactions/detail, rails gives me this error:
ActiveRecord::RecordNotFound in TransactionsController#show
Couldn't find Transaction with id=detail
This makes me think the show route is taking precedence over my collection route, but I can't figure out why. Very similar to this issue: Rails ignores collection route and goes with show action instead, but I don't have a duplicate resources :transactions entry.
Rahul is right. When you visit a web address in your browser, you're making a GET request. Try this instead:
resources :transactions do
collection do
get :detail
end
end
If that's the only route you're nesting, it can be shortened to:
resources :transactions do
get :detail, on: :collection
end

How to force to pass a required url path via get method

I have a route
collection do
get :show_logs
end
And I want the user should request show_logs/[:id].
Forbid user to send show_logs request without required id
What's the better ways to get it ?
UPDATE
If now, I wrote my rule as following,
And trying to access without :id, http://localhost:3000/tool/mvaas/relay_queries/show_logs
I'll get the error ActiveRecord::RecordNotFound in xxx
routes
get '/tool/mvaas/relay_queries/show_logs/:id', to: 'tool/mvaas/relay_queries#show_logs', :via => :get, :as => 'show_logs_tool_mvaas_relay_queries'
namespace :tool do
namespace :mvaas do
resources :relay_queries do
collection do
end
end
end
end
You should put it into member instead of collection
resources :users do
member do
get :show_logs
end
end
It will be accessible with the url /users/:id/show_logs
If you absolutely want the url to be /users/show_logs/:id then you should go with
get '/users/show_logs/:id', to: 'users#show_logs'
before your resources :users do block
You can verify if params exist by following way:
if(params.has_key?(:one))
If exist- request will done.
If absent - redirect/render or show notice.
you could try:
get "show_logs/:id" => "controller#action"
with updates: just write something like:
namespace :tool do
namespace :mvaas do
resources :relay_queries do
collection do
get "show_logs/:id", action: "show_logs"
end
end
end
end

route works one place, not others

This is kind of difficult to communicate but I'll try without pasting all my code. I have Members who have one Mailbox which has many Receipts. In the header layout I have a nav that calls
<%= link_to "Message Center", member_mailbox_path(current_user.member_id) %>
It works on most pages like trails/# , the resource pages for various models
But on other pages, seems like custom route pages, I get this error
No route matches {:action=>"show", :controller=>"mailbox", :member_id=>16}
Running rake routes shows this:
member_mailbox GET /members/:member_id/mailbox/:id(.:format) mailbox#show
Routes are confusing to me, here are my routes for this problem (show message isn't tested yet) ...
resources :members do
resources :mailbox do
resources :receipts do
member do
get :show_message
end
end
end
end
The routes for the pages that are showing the error are similar to this one
match '/my_plays', :to => "trails#my_plays"
match '/my_creations', :to => "trails#my_creations"
So not sure if my routes are right. I wonder if resources :mailbox is correct since I don't have a bunch of resources for that, it's a has_one .... THX
----EDIT--- after changing route per advice:
member_mailbox POST /members/:member_id/mailbox(.:format) mailboxes#create
new_member_mailbox GET /members/:member_id/mailbox/new(.:format) mailboxes#new
edit_member_mailbox GET /members/:member_id/mailbox/edit(.:format) mailboxes#edit
GET /members/:member_id/mailbox(.:format) mailboxes#show
PUT /members/:member_id/mailbox(.:format) mailboxes#update
DELETE /members/:member_id/mailbox(.:format) mailboxes#destroy
You may want to define a mailbox as a singular resource in your routes. Otherwise, Rails will expect you to pass in both the user id and the mailbox id for member_mailbox_path to route to mailbox#show. I believe this is why you're getting a routing error. Since each user has one mailbox, there's no need to make this extra lookup part of the route. So instead of resources :mailbox, you can do resource :mailbox:
resources :members do
resource :mailbox do
resources :receipts do
member do
get :show_message
end
end
end
end
I believe this would generate the following routes:
member_mailbox POST /members/:member_id/mailbox(.:format) mailboxes#create
new_member_mailbox GET /members/:member_id/mailbox/new(.:format) mailboxes#new
edit_member_mailbox GET /members/:member_id/mailbox/edit(.:format) mailboxes#edit
GET /members/:member_id/mailbox(.:format) mailboxes#show
PUT /members/:member_id/mailbox(.:format) mailboxes#update
DELETE /members/:member_id/mailbox(.:format) mailboxes#destroy
Notice that the lack of path names next to GET, PUT, and DELETE doesn't mean they don't exist; they're just repeats of the POST path, but each responds to different HTTP methods.
To render mailboxes#show, you'll need to add a MailboxesController with a show route, which might do a look up for the member:
class MailboxesController < ApplicationController
def show
#member = Member.find(params[:member_id])
# other mailbox code...
end
end
And you'll also create a template at app/views/mailboxes/show.html.erb to render the mailbox show page.
Also, I would recommend against deeply nesting your routes, as in third level :receipts.

Rails - Routes for Nested Resources

I have a conversations controller and a comments controller.
What I would like to do is have the following (from the logs):
Started POST "/conversations/217/comment_beta" for 127.0.0.1
Post the Comments Controller not the Conversations Controller which is what Rails is trying to do now:
AbstractController::ActionNotFound (The action 'comment_beta' could not be found for ConversationsController):
Here is my routes file:
resources :conversations do
resources :comments, :only => [:create, :update,:destroy, :comment_beta], :constraint => {:context_type => "conversations"} do
collection do
post 'comment_beta'
end
end
collection do
get 'read_updater'
end
end
Suggestions? Thanks
your rails routes is actually doing what it is supposed to do. if you conversations/:id/comment_beta to go to your comments controller, either you should change your routes via match or go to the correct url which is /conversations/:id/comments/:comment_id/comment_beta
If you're posting to create a new comment, why aren't you using RESTful routes?
resources :conversations do
resources :comments do
collection do
post 'comment_beta'
end
end
end
should give you /conversations/:id/comments/comment_beta
collection because you don't need an id

Resources