I am trying to create a small rails blog, and have run into an error. I think I've messed up the naming convention of something here... but I can't find anything specific enough to help me and give me the answer.
I have a route of
resources :blog
and a controller which has the following
class BlogController < ApplicationController
def index
#blogs = Blog.all
end
def show
#blog = Blog.find(params[:id])
end
def new
#blog = Blog.new
end
end
When I try to set up a form on the new.html.erb page, it links to routing which states
undefined method `blogs_path'
My route is blog, not blogs... where am I going wrong? I would like the route to be /blog.
Following the conventions, rename your controller file to blogs_controller.rb and the class inside of it to BlogsController. Then, in your routes.rb: resources :blogs. It should all work fine.
As already said, it should be :
resources :blogs
And I think the controller should use the plural too : BlogsController
To find what's wrong with urls you can use rake routes command
Values in first column Prefix are names of helpers you can use as prefix_url or prefix_path
Related
I am trying to redirect from a show action to a custom collection action, but the id param is being carried over, causing the routing to fail. A minimal example:
routes.rb:
resources :first_models, only: [:show]
resources :second_models do
get 'custom_action', on: :collection
end
first_models_controller.rb
class FirstModelsController < ApplicationController
def show
redirect_to controller: 'SecondModelsController', action: 'custom_action'
end
end
second_models_controller.rb
class SecondModelsController < ApplicationController
def custom_action
# Do something
end
end
After setting that up, navigating to /first_models/2 results in an error:
No route matches {:action=>"custom_action", :controller=>"SecondModelsController", :id=>"2"}
I cannot figure out how to strip out the id param from the original request so that the routing matches.
The reason why this happens is that you call redirect_to with a Hash argument. Internally Rails uses url_for to build the final location, which in turn uses default_url_options which uses the ID of the current resource. From the API docs:
Missing routes keys may be filled in from the current request's parameters (e.g. :controller, :action, :id and any other parameters that are placed in the path).
See: http://api.rubyonrails.org/v5.1/classes/ActionDispatch/Routing/UrlFor.html
Solution: Use a named path helper.
Run bundle exec rake routes on the command line to get a list of all your routes and named path helpers. Pick the one that you need and use it as follows:
redirect_to my_named_path_helper_path
It is not the param the problem:
class FirstModelsController < ApplicationController
def show
redirect_to controller: 'second_models', action: 'custom_action'
end
end
You can type rails routes and see all your routes and how rails recognize them.
This should work. However you can be more explicit and use:
redirect_to custom_action_second_models_path
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I'm new to Ruby on rails, and in a month i will start a course on Ruby-on-Rails, but i would like to get some code going before i start the course since i want to learn as much as i can.
I made a project with:
rails new portfolio
Then i did:
rails generate controller portfolio index
To get the front page going.
Rails.application.routes.draw do
get 'portfolio/index'
resources :company
root 'portfolio#index'
end
then:
rails generate controller company
controller:
class CompanyController < ApplicationController
def new
end
end
Then i made a file under views/portfolio/ called index.html.erb where my front page will be.
Under views/company/ i will have a file called company.
When i now go to the url: localhost:3000/company/company i get the error:
The action 'show' could not be found for CompanyController
My CompanyController is this:
class CompanyController < ApplicationController
def new
end
end
Anyone that knows alot about ruby that can just give me a little pointer in the right direction?
Thanks.
Start with a single model and controller for companies. Create a index method inside the app/controllers/companies_controller. Then create the content inside file app/views/companies/index.html.erb to check that everything works, for example:
<h1> Hi! This is root page and index method in CompaniesController! </h1>
In config/routes.rb, you must specify a plural name for companies if you plan to create and process more than one, and leave it as it is, if the entity is the only one company for this project. Set plural name for this resource for this moment to create standard routes for CRUD:
resources :companies
root to: "companies#index"
More about routes you can find in rails guide.
You can try using the built-in scaffold generator in order to quickly generate the application skeleton:
rails generate scaffold companies
The command above will generate controller, model, views and routes with CRUD methods in controller and views for the controller methods. Each view in app/views/"resource_name_plural" adjusted with method in controller in config/routes.rb file. This is how the MVC pattern works.
If you want to create static pages, maybe you should look at the high_voltage gem.
In Rails you need to pay careful attention to pluralization. When declaring routes for a resource it should always be the plural form unless its the rare case where the resource really is singular (there can be only one).
Rails.application.routes.draw do
resources :companies
end
This will route to all companies at /companies and a single company at /companies/:id. If you thus try to get /companies/company it will be routed to the #show action since /company will be interpreted as the id.
Controllers should also be named in plural:
# app/controllers/companies_controller.rb
class CompaniesController < ApplicationController
before_action :set_company, only: [:show, :edit, :update, :destroy]
# GET /companies
def index
#companies = Company.all
end
# GET /companies/:id
def show
end
# ...
private
def set_company
#company = Company.find(params[:id])
end
end
You can use the scaffold command to get a full example of a standard rails CRUD controller:
rails g scaffold companies
If you have the create method, or new, you have to include the show method and index method.
in your routes
resources :companies
resources :portfolios
try in your controller:
class CompanyController < ApplicationController
def new
end
def new
end
def index
#companies = Company.all
end
def show
end
end
and if you have the controller you can create the views and point without problem
localhost:3000/company/company
This, I think it should be something more like this.
localhost:3000/companies/
always plural.
Your controller will look for the view defined in the method. look how it is by default, that of a project of mine. in your place of groups will be companies.
look at the name of the views, are the same names of the methods of your controller. right?
I am new in ruby on rails in windows.. I am following some guide through youtube(https://www.youtube.com/watch?v=BI_VnnOLSKY) but I encountered error "The action 'show' could not be found for PostsController" when I am defining the index method
NOTE: The version of my ruby on rails in windows is latest. This is my first method I will do and to display my first view but it gives me an error.
Question: Should I put the show method to my PostsController?
Routes
Rails.application.routes.draw do
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
resource :posts
root "posts#index"
end
Posts Controller
class PostsController < ApplicationController
def index
end
end
You should change resource :posts to resources :posts and also change the 'application' into 'default' located at 'application.html.erb' file. You will need to add a show method such as:
def show
#post = Post.find(params[:id])
end
and a view as well in show.html.erb
So I have this Ruby on Rails course and I have to create a really simple blog application for it. But it's giving me a hard time!
I have this model called 'articles' and I can see a list with all the articles by navigating to /articles. I made a controller for it by following the Rails documentation.
My teacher also wants me to make an 'admin' area, so I need to access the same list by going to /admin/articles.
How can I do that?
I know this is a really dumb question but I couldn't find the answer anywhere.
Thank you for your time!
you need to create routes for /articles and for /admin/articles
routes.rb
get "/articles" => "articles#index"
namespace :admins do
get "/articles" => "articles#index"
end
And create 2 controllers.
1)
class ArticlesController < ApplicationController
def index
#articles = current_user.articles
end
end
and for admin, create another controller under folder admins.
2)
class Admins::ArticlesController < Admins::BaseController
def index
#articles = Articles.all
end
end
Here inherit Basecontroller for better coding and handling controllers with different namespace. Or you can inherit application controller also.
And one more thing, Please create model with singular name like article only, and plural for controller like articles as per rails standard naming convention.
I'm making an online magazine style website and am having difficulties getting the syntax right for my final part of the project. The relationships are working as they should I am just having trouble calling the intended records.
Each post belongs to a category with category_id being the foreign key. When a user clicks this link, <%= link_to 'News', categories_path(:category_id => 1) %>, I'd like for them to be brought to an index page showing only posts with a category_id matching the parameter in the URL.
I've been messing around in the categories_controller.rb for almost two hours now with no luck. Anyone be so kind as to throw this noob a bone?
There are a few components of what you're trying to do. We'll start with the routing side, and make our way to the controller.
First, you need to make the proper routes. Since the post belongs to a category, you will need to have the category id in order to handle performing any sort of operations on the posts. So we'd need a route like /category/:category_id/posts/:id. Luckily, Rails has something to handle this. If you nest a resources within a resources, it'll generate these routes. So, we end up with this:
resources :categories do
resources :posts
end
And that will get you what you want in terms of routes. But now we have to actually implement it. So, we're going to need to take a look at the controllers. If you notice, all of those routes have a :category_id - so looking up the category shouldn't be too difficult:
class PostsController < ApplicationController
before_action :load_category
private
def load_category
#category = Category.find(params[:category_id])
end
end
Now, you have the category loaded, and it shouldn't be too difficult to implement the other methods from there:
class PostsController < ApplicationController
before_action :load_category
def index
#posts = #category.posts
end
def show
#post = #category.posts.find(id: params[:id])
end
# ...
end
In order to reference the Post index path, you'll have to use category_posts_path helper.
Your problem is that you're trying to use an existing route to handle some new functionality (for which it was incidentally not designed). That categories_path route is meant to take you to your category index.
You need to create a method in your controller to perform the functionality you want to see.
class PostsController < ApplicationController
...
def posts_by_category
#posts_by_category = Post.where("category_id = ?", params[:category_id])
end
...
end
Then you're going to need a view to display your #posts_by_category array (I'll leave this exercise to you).
And now for the key to your problem: you need a route pointing to the posts_by_category method.
get 'posts/posts_by_category' => 'posts#posts_by_category'
Now you should be able to create your link with the correct route:
<%= link_to 'News', posts_by_category_path(:category_id => 1) %>