I'm programming for the first time in ruby and so I'm doing the 'getting started' tutorial from the official website:
http://guides.rubyonrails.org/getting_started.html
I have a problem with 5.7. The tutorial says:
If you submit the form again now, Rails will complain about not
finding the show action. That's not very useful though, so let's add
the show action before proceeding.
And then there is the following code:
post GET /posts/:id(.:format) posts#show
But where do I have to put this code?
Thanks!
What you've depicted is the show member for the posts resource routes. It's not actually code, but rather, a pattern for URL routing. You can see all your routes in this fashion by typing rake routes from the command line.
Breaking down the route:
post GET /posts/:id(.:format) posts#show
# `post` => named route name (available by default only to singular routes)
# `GET` => HTTP method
# `/posts/:id(.:format)` => path made accessible by route
# :id => specifies that the argument passed in as `:id` is available to the controller as `params[:id]`
# `posts#show` => controller is `posts`, action is `show`
You need to create a corresponding show controller action that the route will map to:
# app/controllers/posts_controller.rb
def show
#post = Post.find(params[:id])
end
I just ran into this same problem going through the tutorial. A more direct response to this question is "no where". The reference to that line int the tutorial is only informational. It reads in a way that leads you to believe that you are supposed to add it but there is nothing to add. Just keep going through the rest of the tutorial and all will be well. Maybe someday the author will read this and fix it.
Adding the following (bolded) sentence would make the instructions in 5.7 more clear:
If you submit the form again now, Rails will complain about not finding the show action. That's not very useful though, so let's add the show action before proceeding. Running 'rake routes`now results in the following:
post GET /posts/:id(.:format) posts#show
If you have the PostsController in your application, then you must have the following in the config/routes.rb
resources :posts
So that it will generate 7 default routes for the posts controller where show is a default action.
When you do rake routes in your console, it will show you all the routes for your application. From those routes, you can get
post GET /posts/:id(.:format) posts#show
The above is the routes, not the code. So it states that you have a controller named "posts" and "show" is an action of it. Which can be accessible via '/posts/:id' with "get" method.
Make sure the private section comes after the def show block
class PostsController < ApplicationController
def new
end
def create
#render text: params[:post].inspect
#post = Post.new(post_params)
#post.save
redirect_to #post
end
def show
#post = Post.find(params[:id])
end
private
def post_params
params.require(:post).permit(:title, :text)
end
end
Nothing needs to be added to the config file, as some guys already said, is the information that appears after run the command
rake routes
Just adding the show action to the post_controller.rb and the show.html.erb view is enough to be able to post the information and continue with the example.
Related
I'm working on a Rails project that is giving me some problems. I've got a controller characters_controller.rb that has two methods.
class CharactersController < ApplicationController
before_action :authenticate_player!
def view
#character = Character.find(params[:id])
unless #character.player_id == current_player.id
redirect_to :root
end
end
def new
end
end
I've got routes set up for each of those.
get 'characters/:id', to: 'characters#view'
get 'characters/new', to: 'characters#new'
The first route works fine. I can get go to /characters/1 and I'm shown the appropriate view and the requested information. If I visit /characters/new I'm shown an error that references characters#view.
raise RecordNotFound, "Couldn't find #{name} with '#{primary_key}'=#{id}"
and
app/controllers/characters_controller.rb:6:in `view'
So /characters/new is trying to get a Character from the database with an id of "new" but that doesn't work well. Any idea what I may be doing wrong?
Order matters in routes.rb, the router will find the first route that matches.
In your case, it would never go to characters#new, because the line above it will always match.
A simple solution would be to swap the two lines.
A better solution might be to use resource routing as documented in the Rails routing guide.
Rails parses routes sequentially and therefore it is considering 'new' as the :id for characters/:id route (which encountered first).
Just swap the order of routes as follow:
get 'characters/new', to: 'characters#new'
get 'characters/:id', to: 'characters#view'
If using this order in your routes.rb, for /character/new request, rails will understand that request is handled by view action with paramas[:id] = 'new'
Let characters/new before the other will resolve your problem:
get 'characters/new', to: 'characters#new'
get 'characters/:id', to: 'characters#view'
Try to use resourceful routes, much cleaner:
resources :characters, only: [:new, :show]
Also I suggest rename def view to def show to follow rails convention
Just use
resources :characters, :path => "characters"
in your routes.rb
I am sorry for asking what may be a remedial question, but in learning rails i was trying to follow along note for note in this tutorial:
http://guides.rubyonrails.org/getting_started.html#configuration-gotchas
I am fie to section 5.7 - showing the results of the post, as instructed I add this line to routes.rb
post GET /posts/:id(.:format) posts#show
and the show method in posts_controller.rb:
class PostsController < ApplicationController
def new
end
def create
#post = Post.new (post_params)
#post.save
redirect_to #post
end
def show
#post = Post.find(params[:id])
end
private
def post_params
params.require(:post).permit(:title, :text)
end
end
my routes.rb file is
Listing::Application.routes.draw do
get "welcome/index"
post GET /posts/:id(.:format) posts#show
resources :posts
# You can have the root of your site routed with "root"
root 'welcome#index'
end
Here is the error:
C:/Ruby-Projects/listing/config/routes.rb:4: syntax error, unexpected
':', expecting keyword_end post GET /posts/:id(.:format) posts#show ^
Rails.root: C:/Ruby-Projects/listing
Application Trace | Framework Trace | Full Trace This error occurred
while loading the following files:
C:/Ruby-Projects/listing/config/routes.rb
I am running rails 4.0, ruby 2.0 on 64 bit windows 8.
Admittedly I don't know what that line in the routes.rb is trying to do, but my goal was to type this in and pickup what i can, before digging into the subject full bore. i cut and pasted the line, typed it in, and tried changing a couple of things - without results.
I am tired, and feeling stupid, so I am here asking for your help.
Thank you in advance.
That line in section 5.7 is just showing you the output of rake routes, it's not meant to be in your config/routes.rb file.
The line resources :posts in routes.rb generates the show posts route for you, test it by removing the line: post GET /posts/:id(.:format) posts#show and then running rake routes on the command line.
i'm new to the ruby world i have started learning it this afternoon :)
i had the same error as yours and i solved it by changing the way routes have been written to the suggested style within the routes.rb file.
instead of what have been written on that tutorials copy and past this into your routes.rb
Blog::Application.routes.draw do
get "welcome/index"
resources :posts
root 'welcome#index'
get '/posts/:id(.:format)' => 'posts#show'
get '/posts(.:format)' => 'posts#index'
end
save and check your posts url as suggested on that tutorials
http://localhost:3000/posts
it should work for you.
When I go to my localhost:3000/users page, I get:
Unknown action
The action 'index' could not be found for UsersController.
If you were following Hartl's tutorial,then accessing localhost:3000/users will cause this error. Try localhost:3000/signup instead.
You need not define the default actions (assuming appropriate http method), all you need to do is add the following to your config/routes.rb
resources :users
First you need to make sure that your controller actually has an index action, so
class UsersController < ApplicationController has to include the def index ... end in it.
Also, make sure your routes are set up correctly using
resources :users
and check it by typing
rake routes
in the terminal to check that the routes are right.
You might also want to check that the root is set up correctly in the config/routes.rb file
if you got the same problem with me (I cant access the localhost:3000/users but I can access my localhost:3000/signup), it might be works for u.
First, in your users_controller.rb (Controller for Users) , add
def index
end
Then , make a file "index/html/erb" in your app/views/users/index.html.erb
and put this code
<% controller.redirect_to "/signup" %>
You might have to rerun your server, and it works on my problem.
Remember, if you've included
get 'signup' => 'users#new
resources :users
…in your routes.rb file, then you need to use localhost:3000/signup instead. I believe if you removed get 'signup' => 'users#new and left only resources :users then using localhost:3000/users would take you to the new user signup form.
Remove the debugger line. Also, make sure you have exit the rails console.
class UsersController < ApplicationController
def show
#user = User.find(params[:id])
debugger
end
def new
end
end
I'm trying to make a simple link that will toggle my "status" attribute in my model from "pending" to "active". For example, when I first create a user, I set the status to "pending". Then when I show the list of users, I add a button that should change that user's status to "active". I tried this via a custom action (is this a good approach?) but I'm having trouble with the auto-generated named route.
in my user index.html.haml:
button_to "Manually Activate", activate_user_path
in routes.rb:
resources :users do
get :activate, :on => :member
in users_controller.rb:
def activate
#user = User.find(params[:id])
#user.update_attribute(:status, 'Active')
redirect_to #user
end
this seems to work when I go to say, /users/1/activate, as the status will update. However, the /users page doesn't show and gives me error:
ActionController::RoutingError in Users#index
No route matches {:action=>"activate", :controller=>"users"}
ie, it is having a problem with the activate_user_path I specified in my view. (However if I use another named-routes-style path that I haven't specified in my routes.rb to test it out, I get
NameError in Users#index
undefined local variable or method `blahblah_user_url' for #<#<Class:0x00000102bd5d50>:0x00000102bb9588>
so it seems that it knows it's in the routes.rb but something else is wrong? I'm really new to rails and would appreciate the help!
thanks!
Your link should look like this:
button_to "Manually Activate", activate_user_path(#user)
You need to add what user you want to activate.
A number of problems, I can see.
Firstly you should NOT update the database using a GET request.
Secondly button_to will provide you with an inplace form which when clicked will POST to your app.
Thirdly, the way you have your routes setup, you need to provide the user in the path (you've tested it by forming the url in the browser already).
run
rake routes
on the command prompt to see how your routes look and the name you can use to generate those routes.
I suspect you need to use
button_to "Manually Activate", activate_user_path(user)
(user or #user or whatever is the user object). In your button_to call and change the "get" to "post" in the routes file.
resources :users do
member do
post :activate
end
end
I have an application_controller spec that is failing since I removed the controller/action route from routes.rb. I get the following error:
No route matches {:controller=>"application", :action=>"index"}
I had many tests fail in the same way, but was able to fix them by including the correct parameters in the get call. So for instance, if I wanted to get the standard show route for posts in my spec, I had to change
get :show to get :show, :id => '1'
Unfortunately, I'm not sure now what to pass along for the application controller specs. I've included my test below.
describe ApplicationController do
it "should find the latest published posts and assign them for the view" do
Post.should_receive(:latest).and_return(#posts)
get :index
assigns[:posts].should == #posts
end
it "should find the latest approved comments and assign them for the view" do
Comment.should_receive(:latest).and_return(#comments)
get :index
assigns[:comments].should == #comments
end
end
Consider the ApplicationController as an abstract class not intended to be used for requests. All new controllers generated will inherit from ApplicationController so it is a nice place to put shared behavior.