Am new to ruby on rails. Here Am trying to display image from database. To this effect, I leverage solution found here
link. but when I run my script it displays error
No route matches {:action=>"show", :controller=>"attachments_controller", :id=>17}
Please what am I doing wrong with the route.
Routes
Rails.application.routes.draw do
resources :attachments, only: [:index, :new, :create, :destroy]
root "attachments#create"
get "attachments/show" => "attachments#show"
end
attachments_controller
class AttachmentsController < ApplicationController
def show
#attachment = Attachment.find(params[:id])
send_data #attachment.data, :filename => #attachment.filename, :type => #attachment.content_type
end
end
show.html
<%= image_tag url_for(:controller => "attachments_controller", :action => "show", :id => #attachment.id) %>
The error message you provided states:
No route matches {:action=>"show", :controller=>"attachments_controller", :id=>17}
The routes file you provided shows the routes you created:
resources :attachments, only: [:index, :new, :create, :destroy]
get "attachments/show" => "attachments#show"
Running rake routes will show that you've created the 4 routes in the first line, plus a route that responds to 'attachments/show'. If you really want to define the route like this, you should try:
get "attachments/:id", to: "attachments/show"
Your first route only responds to the word show, and would supply no params. The last route will take whatever comes after attachments, and pass it to the show action of the attachments controller as a paramater called 'id'.
Of course the easiest way to do all of that is to get rid of it all, and simply change the first route to:
resources :attachments, only: [:index, :new, :create, :destroy, :show]
Letting rails create the show route for you is exactly the same as manually defining it, and obviously reads a lot better
change
<%= image_tag url_for(:controller => "attachments_controller", :action => "show", :id => #attachment.id) %>
to
<%= image_tag url_for(:controller => "attachments", :action => "show", :id => #attachment.id) %>
Related
I want to modify the value in the object. However, modified routing does not work properly.
#routes
root 'freelancers#index'
get 'new' => 'freelancers#new'
post 'category' => 'freelancers#category'
get 'video' => 'freelancers#video'
get 'video/show/:id' => 'freelancers#video_show'
get 'video/new' => 'freelancers#video_new'
post 'video/create' => 'freelancers#video_create'
get 'video/:id/edit' => 'freelancers#video_edit'
patch 'video/show/:id/update' => 'freelancers#video_update'
get 'design' => 'freelancers#design'
Form code:
<%= form_for(#video, :html => { :multipart => true, :id => #video.id, :url => '/video/show/:id/update' }, method: :patch ) do |f| %>
i expect the output of /video/show/3/update
but the actual output is video.3
Fast way:
Change this line:
patch 'video/show/:id/update' => 'freelancers#video_update'
To:
patch 'video/show/:id/update' => 'freelancers#video_update', as: :update_video
This will create update_video_path as named helper in your application. Then you will be able to use it:
<%= form_for(#video, :html => { :multipart => true, :id => #video.id, :url => update_video_path(#video) }, method: :patch ) do |f| %>
You can check the documentation for more information.
Right way:
Seems that you need to refactor your routes and controllers. It is a good practice when your controller covers one resource. In your case it seems that you need at least two controllers: FreelancersController and VideosController, and videos resources should be nested inside freelancers.
For example, it might look like this:
root 'freelancers#index'
resources :freelancers, only: [:index, :new] do
collection do
get :design
post :category
resources :videos, only: [:index, :new, :create, :show, :edit, :update]
end
end
I left design and category in the example as is, but probably these routes also need the separate controllers.
This way is better, because:
Routes become more understandable and more supportable
Your controllers are responsible for only one resource each
You get a bunch of path and URL helpers without additional work
Your application follows the conventions
Of course, if you need to customize application URLs, Rails provides you the way, but in most cases following the convention is better.
You can find more information in the documentation.
In my application I have a link_to helper method:
<%= link_to "Downgrade", :controller => :subscriptions, :action => :downgrade, class: "btn btn-primary", remote: true %>
In my controller I have this code:
class SubscriptionsController < ApplicationController
respond_to :js
def downgrade
# some code
end
end
I am getting this error:
No route matches {:action=>"downgrade", :class=>"btn btn-primary", :controller=>"devise/subscriptions"}
Here is my routes.rb code:
Rails.application.routes.draw do
resources :wikis
devise_for :users
resources :users, only: [:update]
root to: 'welcome#index'
resources :charges, only: [:new, :create]
end
I know Rails is expecting a route for this but I don't know what route I would use since the method isn't a restful verb. Maybe there is another way without using the link_to which allows me to directly call a controller method from a view? Maybe I need to restructure where things are as well. Any help is appreciated.
Let me know if there is more code you would need to fully assess this situation.
Basic setup
first you need to setup your route in routes.rb
get 'downgrade' => 'subscriptions#downgrade', :as => :downgrade_subscription
This will redirect /downgrade to your subscriptions controller & downgrade action. The as option saves this route into a variable you can call from all your views.
<%= link_to "Downgrade", downgrade_subscriptions_path, class: "btn btn-primary", remote: true %>
Further configuration
You can also nest this route inside your subscription resources like so:
resources :subscriptions do
get 'downgrade' => 'subscriptions#downgrade', :as => :downgrade_subscription
end
This will create the path /subscriptions/downgrade instead of /downgrade.
The Rails Docs on routing does a great job explaining this in more detail. Definitely check it out!
or you can try this on your routes.rb
match '/downgrade_subscription', :to => 'subscriptioni#downgrade', :via => :get
I have a resource in my application that seems correct but when I open index, I get an error: undefined local variable or method 'new_beta_request_path'. This happens with beta_request_approval path also.
My links look like <%= link_to 'New Beta Request', new_beta_request_path, :class => "btn" %> and <%= link_to "Approve", beta_request_approval_path %>.
All of the paths seem correct to me but something is obviously missing...
In my routes.rb, I have:
resources :beta_requests, :only => [:index, :edit, :create, :update, :destroy]
match '/request_invite', to: 'beta_requests#new', :as => "request_invite"
match 'beta_requests/:id/approve', to: 'beta_requests#approve', :as => "beta_request_approval", :via => :put
When I run Rake Routes, I get the following:
beta_requests GET /beta_requests(.:format) beta_requests#index
POST /beta_requests(.:format) beta_requests#create
edit_beta_request GET /beta_requests/:id/edit(.:format) beta_requests#edit
beta_request PUT /beta_requests/:id(.:format) beta_requests#update
DELETE /beta_requests/:id(.:format) beta_requests#destroy
request_invite /request_invite(.:format) beta_requests#new
beta_request_approval POST /beta_requests/:id/approve(.:format) beta_requests#approve
Can anyone see what I apparently cannot?
There's no :new in the only array? You can either add it:
resources :beta_requests, :only => [:index, :edit, :new, :create, :update, :destroy]
or remove the hash argument entirely, since this way all resource actions are defined anyway.
You want to use request_invite_path instead of new_beta_request_path in your link. That is:
<%= link_to 'New Beta Request', request_invite_path, :class => "btn" %>
This is available to you, since you set the :as option on the request_invite route definition.
As for the other error, I notice that your rake routes lists beta_request_approval as using the POST verb and your routes.rb defines that route using a :via => :put option.
In routes.rb:
resources :conversations, only: [:index, :show, :new, :create, :destroy] do
collection do
get :inbox
end
In my controller:
def inbox
<stuff>
end
In my view (using haml):
=link_to 'Inbox', inbox_conversations, :id => 'load-inbox', :class => 'message-control-highlight', :remote => true
I get the following error on page load:
undefined local variable or method `inbox_conversations' for #<#<Class:0x3d51470>:0x3d59198>
In my view, if I replace inbox_conversations with a "#", I don't get any errors on page load. I've tried appending inbox_conversation with likely classes, such as current_user and current_user.mailbox. I've also tried changing the routing from collection to member--and even taking it out of any collection/member block. What could be the problem here?
Try using inbox_conversations_path or inbox_conversations_url
=link_to 'Inbox', inbox_conversations_path, :id => 'load-inbox', :class => 'message-control-highlight', :remote => true
You need to append _path or _url to your routes, e.g.
= link_to 'Inbox', inbox_conversations_path
See the complete Rails Routing guide for all the details:
http://guides.rubyonrails.org/routing.html
In my AdminController, I have methods named as edit, update and update_admin. And in route.rb
resources :session, :only => [update]
match '/:controller(/:action(/:id))'
end
When I navigate the url '/users/edit/1' matches. From this page i want to call the action method in update_admin in AdminController. How to do this?
My edit.erb has
<%= render :partial => '/submit', :locals =
> {:button_html => f.submit('Update'), :validate_present => true}
%>
at first, to check your routes go to console and do
rake routes | grep session
there you will get list all routes of your rails application (matched to the grep)
at second i dont get your routes.rb
would you do
resources :session, :only => [update] do
match '/:controller(/:action(/:id))'
end
or
resources :session, :only => [update]
match '/:controller(/:action(/:id))'
end
these are 2 different things. i think you want the last one. but here we go, there is another problem
resources :session, :only=>[update]
this throws an error.(undefined local variable or method `update' for #)
if you want to specify actions, you need to do it as a key
resources :session, :only=>[:update]
but you also want the edit message, (edit is the form, update the action to save the changes) so you have to do
resources :users, :only=>[:edit, :update]
now check your rake routes and see voila!
edit_session GET /session/:id/edit(.:format) {:action=>"edit", :controller=>"session"}
session PUT /session/:id(.:format) {:action=>"update", :controller=>"session"}
//edit
if you want to do this in your admin_controller you should have a namespace
#i take example for a user
namespace :admin do
resources :user :only => [:edit, :update]
end
if you want now to link to it from a view the route is named
edit_admin_user_path
and in a form you need to bring the namespace also in the form_for like:
=form_for [:admin, #user] do |f|