I have
resources :articles
and in article.rb
def to_param
"#{id}-#{name.downcase.gsub(/\s+/, "_")}"
end
So the URL will be like
www.example.com/articles/1-Name-of-the-first-article
I am now trying to find a simple solution to always substitute "article" in the URL with "encyclopedia". So the path should be
www.example.com/encyclopedia/1-Name-of-the-first-article
Is there a simple solution?
Really simple.
routes.rb
resources :articles, :path => :encyclopedia
Related
I'd like to define a model as a resource to get all the REST URLs.
But, I'd like to disable some of the generated routes (e.g., DELETE). Is there an easy API for this, or do I just need to declare all the routes individually?
you have two ways of doing this
in config/routes.rb
1) as #emm, suggested define only the routes you want
2) use except keyword to exclude routes
Ex: Excluding destroy action
resources :books, :except => [:destroy]
read more here
HTH
Something like this in routes.rb:
resources :photos, :only => [:index, :show]
See more here.
You can also exclude specific actions like this:
resources :articles, except: :destroy
Maybe I'm stupid but Rails provides this nifty syntax for generating URL's like so:
url_for([user, comment]) # => /users/1/comment/1
Passing :edit allows me to create something like this:
url_for([:edit, user, comment]) # => /users/1/comment/1/edit
but is there some way to do following?
url_for([:new, user, comments]) # => NoMethodError: undefined method `new_user_comments_url'
UPDATE: Added more information.
My routes.rb:
resources :users do
resources :comments
end
resources :posts do
resources :comments
end
My problem here is, that I can't use Rails auto-generated url helper (user_comments_url), because I'm sharing the views for both user comments and post comments.
There are two workarounds (but no one feels like the "Rails"-way) for my problem:
Adding logic to the view, e.g. some if conditions.
Defining my own url helpers like new_parent_comment(user_or_blog).
Ok, found a solution, but I'm not sure if this is the intended one:
url_for([:new, user, :comment]) # => '/users/1/comments/new'
url_for([:new, post, :comment]) # => '/posts/1/comments/new'
Stuck with the same problem, and found next solution (tested on Rails 5.2):
url_for([user, Comment, action: :new])
where Comment model class name.
By the way, action also could be :edit.
According to the Rails Docs url_for uses the class name of the object passed to generate the RESTful route. It also states that with nested routes it can not make this assumption correctly:
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).
I would suggest using a named route here something like new_user_comment_path(). I am assuming you have set up your routes.rb something like:
resources :users do
resources :comments do
end
end
Additionally you can run rake routes to print out the proper names for all your routes.
Hope this helps,
/Salernost
Could this simply be a typo? I think the last line should read comment, not comments:
url_for([:new, user, comment])
(Assuming your comment variable has been defined.)
So I'd like to have urls on my site like http://foobar.com/hadees that goes to someone's profile. However when registering usernames how do I make sure they don't pick something that will conflict with my existing routes?
I'm guessing I need to get a list of the existing routes but I'm not sure how to do it.
A short google search gives me that:
http://henrik.nyh.se/2008/10/validating-slugs-against-existing-routes-in-rails
In rails 3 the method has moved to Rails.application.routes.recognize_path
So I summarize :
class User < ActiveRecord::Base
validates_format_of :name, :with => /\A[\w-]+\Z/
validates_uniqueness_of :name
validate :name_is_not_a_route
protected
def name_is_not_a_route
path = Rails.application.routes.recognize_path("/#{name}", :method => :get) rescue nil
errors.add(:name, "conflicts with existing path (/#{name})") if path && !path[:username]
end
end
Good question. Through a little tinkering, I found that you can get the routes in your app via:
Rails.application.routes.routes.collect{|r| r.path}
Today I tried to follow the basic "Twitter" tutorial on :
--> http://www.noupe.com/ajax/create-a-simple-twitter-app.html
But in the midle of the tutorial I have an issue.
It says that you should edit /config/routes.rb and add this piece of code :
ActionController::Routing::Routes.draw do |map|
map.resources :posts
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
end
It was written a while ago so there are probably incompatibilities with rails3 especially with the new routing synthax.
So I tried to fix changing it in :
Standart::Application.routes.draw do |map|
resources :posts
match ':controller/:action/:id'
match ':controller/:action/:id.:format'
end
Where "Standart" the name of the application is.
You need a root route:
resources :posts
root :to => 'posts#index'
You should try to avoid those catch-all routes that Rails 2 used. If you need other routes, try to see what fits into resourceful routes and use those, and create specific routes with the Rails 3 DSL for anything that doesn't fit.
What I am trying to achieve is something similar to Github's way for routes. E.g. I have a project with the name 'question' results in the URL /hjuskewycz/question. So my goal is to have routes where the first segment is the username and the second the project's name.
I tried a couple of different approaches, this is the one I am stuck with right now:
scope ":username" do
resources :projects, :path => "" do
resources :pictures
end
end
Using
project_path :username => project.owner.username, :id => project.to_param
works as expected. However, it's tedious to always specify the username although it's always the owner's username. I would very much prefer
project_path(:id => project.to_param)
I know about default_url_options and url_for and I digged in the code. However, polymorphic_url doesn't use default_url_options.
I tried in routes.rb:
resources :projects, :path => "", :defaults => {:username => Proc.new { "just_testing" }}
since you can use a proc for constrains, but haven't got it working either.
I tried in project.rb
def to_param
"#{owner.username"/#{project.title}"
end
I spent already too much time on this problem and my current approach uses a convenience method to add the :username parameter. Nevertheless, I think using this method all over the place just to add an entry stinks (bad code smell). I wonder if there is a more elegant solution to this problem.
I think you should not make things complicated here, just use something like this:
In Routes.rb
match ':username/:projectname/' => 'projects#show_project' , :as => :show_project
and in project_controller, just define this
def show_project
#user =User.find_by_username(params[:username])
#project =Project.find_by_slug(params[:projectname])
end
Simpler is better, it saves time and easy to understand for others
You want to do something like this in your controller:
before_filter :set_username
def set_username
Rails.application.routes.default_url_options[:username] = #user.name
end