I have an edit and update methods as follows:
cmdbs_controller.rb
def edit
#evm = Evm.find(params[:id])
end
def update
#evm = Evm.find(params[:id])
if #evm.update(evm_params)
redirect_to #evm
else
render 'edit'
end
end
and routes as follows:
resources :cmdbs do
get :autocomplete_client_name, :on => :collection
collection do
get 'test'
end
end
The problem is that i get an error when submit my edit:
undefined method `evm_url' for #<CmdbsController:0x007fb33ac47d00>
and points me to the redirect_to #evm line.
BTW i am using patch and my url looks like that:
http://localhost:3000/cmdbs/1
The line redirect_to #evm translates to redirect_to evm_path(#evm.id). It uses evm_path because the class of #evm is Evm. So with that, it is expecting to have something like resources :evms in the routes. This means that you have to have another controller called EvmsController. Doing a redirect_to #evm basically redirects to the show action of EvmsController. I'm not sure if that is what you want to happen but that is what Rails is trying to do. Without any other stuff in your routes file, Rails don't know where to redirect.
Related
I am trying to go through the 'Ruby on Rails Getting Started' tutorial(guides.rubyonrails.org) and I am running into this issue I cannot seem to figure out. I reached the point in the tutorial where I can create an article, but the redirect to see the article immediately after creation does not work and I get an error that says:
NoMethodError in Blog::ArticlesController#create
undefined method `article_url' for #<Blog::ArticlesController:0x00007f814841af20>
Here is my article controller code:
class Blog::ArticlesController < ApplicationController
def new
#article = Article.new
end
def create
#article = Article.new(params.require(:article).permit(:title, :category, :text))
#article.save
redirect_to #article # <-- This line throws error
end
def show
#article = Article.find(params[:id])
end
end
and here is my routes.rb (omitted irrelevant code):
Rails.application.routes.draw do
# <-- other get functions here
get 'blog', to: 'blog#index'
namespace :blog do
resources :articles # <-- Suggestions were to make these plural
end
root 'about#index'
end
The only deviation I have done from the tutorial is that I wanted to place the articles in a name space, as well as 1 extra value to enter in the form(category). The only suggestions for fixing my issue when I searched was to make resource into plural but my code already has this and to add #article = Article.new into def new in the controller but this addition made no difference.
I found a work around that will properly redirect after creating a new article that is the line as follows:
redirect_to :action => "show", :id => #article.id
But this doesn't seem like the "Rails Way"(Convention over Configuration), and I really don't understand why the suggested code in the tutorial is not working for me
The Rails-ey way to redirect to the proper route would be to first check in the terminal with rails routes.
There you will see if you want to route to articles#show under the namespace blog that the prefix (first column) is blog_article.
You can use this prefix with the _path method like so:
redirect_to blog_article_path(#article)
I feel like this is simple but I'm banging my head against the wall. I'm trying to tell my Rails app that if one parameter is present (signature in this example) that I want to redirect home. Here's my code:
<%= if #pc.signature.present? %><% redirect_to "pages#home" %><%end%>
I keep running into a syntax error. This is in the edit.html.erb file by the way.
Perhaps in your controller you didn't define #pc? also, use path instead of 'pages#home'. it should look more like this:
def edit
#pc = Pc.find(params[:id]) #or whatever your logic is
redirect_to root_path if #pc.signature.present?
# otherwise 'edit' template will be rendered
end
You need to do that on your action controller, not in the view
def your_action
if #pc.signature.present?
redirect_to 'your_path_or_url'
end
end
I'm using Rails 4 with strong parameters to try to find a user by a parameter called "provider_id".
The hope is that I'll be able to make a call with my API to a URL such as:
url.com/api/v1/user?provider=facebook?provider_id=12345
My routes are as follows: routes.rb
namespace :api do
namespace :v1 do
resources :users
match '/:provider/:provider_id', to: 'users#find_by_provider', via: 'get'
end
end
My Strong parameters are:
def user_params
params.require(:user).permit(:name, :age, :location, :provider, :provider_id) if params[:user]
end
My Function is:
def find_by_provider
#user = User.find(params[:provider_id])
respond_to do |format|
format.json { render json: #user }
end
end
Currently, I'm testing with:
url.com/api/v1/facebook/12345
and it is returning:
"{"provider"=>"facebook",
"provider_id"=>"12345"}"
which is good! But I now get the error: "Couldn't find User with id=12345"
Also, somewhat related: occasionally I receive an error that says "param not found: user".
Any suggestions? Thanks!
Change:
#user = User.find(params[:provider_id])
To:
#user = User.find_by(:provider_id => params[:provider_id])
find method will alyways search objects with the id column. Use the where method to search by other criterias/columns
Use:
#user = User.where(provider_id: params[:provider_id]).take
Take a look at http://guides.rubyonrails.org/active_record_querying.html if you want to learn more about the active record query interface.
This is a perfect example where to use find_by! (note the !).
#user = User.find_by!(:provider_id => params[:provider_id])
It works like find_by and returns one User. But if the user is not found it raises an ActiveRecord::RecordNotFound error. That exception is handled by Rails automatically and is turned into a 404 error page.
When saving our Video object we get a no method vide_url error when trying to redirect to the video#watch action and view the object
Admin/Video/Controller
def create
#video = Video.create(user: User.first, title: params['title'], description: params['description'], file: params['video']['file'])
redirect_to #video
end
Video/Controller
def index
#videos = Video.page(params[:page]||1)
end
def watch
#video = Video.find_by!(id: params[:id])
end
Routes
get "video/index"
get "video/watch/:id" => 'video#watch'
namespace :admin do
resources :video
resources :playlist
end
Any idea what is going on? Is it because we are using custom routes for the videos?
Yes, it is your custom routes. redirect_to #video essentially calls url_for #video. From the docs for url_for:
Relying on named routes
Passing a record (like an Active Record) instead of a hash as the
options parameter will trigger the named route for that record. The
lookup will happen on the name of the class. So passing a Workshop
object will attempt to use the workshop_path route. If you have a
nested route, such as admin_workshop_path you’ll have to call that
explicitly (it’s impossible for url_for to guess that route).
So, because you've got a namespace around that resource you'll need to do:
redirect_to admin_video_path(#video)
or
redirect_to admin_video_url(#video)
Update
If you want to redirect to the watch action you'll need to either redirect to a hash of options including that action:
redirect_to controller: :video, action: :watch, id: #video.id
Or give your watch route a name in routes.rb:
get "video/watch/:id", to: 'video#watch', as: :watch_video
And redirect to that named route:
redirect_to watch_video_url(#video)
Please, Try the followings.
def create
#video = Video.create(user: User.first, title: params['title'], description: params['description'], file: params['video']['file'])
redirect_to admin_video_path(#video)
end
So I have a ChatsController, and from my index action, I'm trying to redirect to a custom action, "decide":
def index
#chat = Chat.customfind(params[:search])
if(#chat.is_a?(Array))
session[:chats] = #chat
redirect_to :action => 'decide'
else
respond_to do |format|
format.html { redirect_to #chat if !#chat.nil? }
end
end
def decide
#chats = session[:chats]
#choice = Chat.find(params[:id])
redirect_to #choice if !#choice.nil?
end
..where #choice is going to be decided by the params of the form on the decide page. But for some reason, instead of redirecting to decide, Rails redirects to show:
Started GET "/chats/decide" for 127.0.0.1 at 2012-03-14 17:13:36 -0400
Processing by ChatsController#show as HTML
Parameters: {"id"=>"decide"}
..............
Can anyone explain how to fix this?
Edit:
I'm assuming this is what you want... the relevant parts of my routes.rb:
match "chats/decide" => "chats#decide"
resources :chats do
member do
post 'send_message'
end
end
get "chats/logout"
..yeah it's a bit of a hodgepodge :/
It seems you are trying to achieve the following:
Find all chats matching a given search string
If 1 chat is found, redirect to it
If 2+ chats are found, redirect to /chats/decide so the user can pick one
I would implement this as follows:
1) Update routes.rb as follows:
resources :chats do
member do
post :send_message
end
collection do
get :decide # Produces the '/chats/decide/' route
end
end
2) Change your chats#decide action to this:
def decide
#chats = session[:chats]
end
3) When you list the available chats in your decide.html.erb file, link them directly to the appropriate show link.
4) Be explicit about your redirect in chats#index:
redirect_to :controller => 'chats', :action => 'decide'
Your chats#decide action should not respond differently based on whether it's receiving an id or not. You can link directly to the specific chats in that view.