How to link to :id pages rails - ruby-on-rails

Been trying to find out a better way to link to pages that contains /:id's in them. Because the way I'm doing it now works but can easily break if I change something.
Currently I have two of these examples. One to link to your profile done like this:
<li><%= link_to "Your profile", root_url + "users/#{current_user.id}" %></li>
and the other:
<%= link_to "Apply now", root_url + "answers/#{f.id}" %>
how do I make it so that I don't have to rely on the manual change of this. On my rake routes I cant write 'answers_path/#{f.id}' for example as it doesn't show me any path.
So how do I do this? My routes setup for these two are currently:
match '/answers/:id', to: 'answers#show', via: 'get'
match '/users/:id', to: 'users#show', via: 'get'

Instead of using match I would define resources routes
resources :users, :answers
Now you can use:
<%= link_to 'Your Profile', current_user %>
<%= link_to 'Apply Now', f %>
You can learn more about rails path helpers and resource routing here - http://guides.rubyonrails.org/routing.html
Also, if you don't need all the CRUD actions, you can use only:
resources :users, :answers, only: :show

The following should do it for you.
<li><%= link_to "Your profile", user_path(current_user.id) %></li>
and
<%= link_to "Apply now", answer_path(f.id) %>
I do, however, recommend you review the following Rails Guide: http://guides.rubyonrails.org/routing.html

Related

Create a 'resources' route for static_pages controller in rails 6.1.3

total newbie here ^^
So I have a bunch of static pages in my footer that I would like to create a route for.
Right now, I am using get to create the routes as such:
Rails.application.routes.draw do
root 'static_pages#home_page'
get 'static_pages/secret'
get 'static_pages/stripe_button'
get 'about_us', to: 'static_pages#about_us'
get 'rules', to: 'static_pages#rules'
get 'faq', to: 'static_pages#faq'
get 'community', to: 'static_pages#community'
get 'terms', to: 'static_pages#terms'
get 'privacy', to: 'static_pages#privacy'
end
Ideally, I am trying to condense all of that into a resources like so:
resources :static_pages, only: [:index] do
get :terms, :community, :privacy, :rules, :faq, :about_us, :stripe_button, :secret
end
Here is the footer li for the pages:
<div class="col">
<ul>
<li><%= link_to "About Us", 'about_us', class: 'nav-link d-inline-block' %></li>
<li><%= link_to "Rules", 'rules', class: 'nav-link d-inline-block' %></li>
<li><%= link_to "FAQ", 'faq', class: 'nav-link d-inline-block' %></li>
</ul>
</div>
<div class="col">
<ul>
<li><%= link_to "Community", 'community', class: 'nav-link d-inline-block' %></li>
<li><%= link_to "Terms", 'terms', class: 'nav-link d-inline-block' %></li>
<li><%= link_to "Privacy", 'privacy', class: 'nav-link d-inline-block' %></li>
</ul>
</div>
How do I get rid of all the gets and condense all of it into one resources?
ruby 2.7.1
rails 6.1.3
Thx a lot :)
First of all, resources is a concept that revoles around an actual resource, or record if you will. Your static routes don't really follow that, so you the way you did it is actually the right way to do it (see also here: https://guides.rubyonrails.org/routing.html#non-resourceful-routes).
If your sole purpose is refactoring your routes file, I wouldn't worry too much, in fact I would leave it as is because I think it's more important to follow the concepts.
If you still want to go ahead and you don't care too much what the actual urls look like you can do it like so:
resources :static_pages, only: [:index] do
collection do
get :terms, :community, :privacy, :rules, :faq, :about_us, :stripe_button, :secret
end
end
Urls will look like this then /static_pages/terms.
The collection makes sure there is no :id needed in the routes. You can always double check in the terminal with rails routes - also in order to find the prefix for the link_to helper (will be terms_static_pages_path).
You may find ideas there
Rails routing: resources with only custom actions
This could be your solution:
scope '/', controller: :static_pages do
get :terms, :community, :privacy, :rules, :faq, :about_us, :stripe_button, :secret
end
If you don't want to manually type all actions, you can use the class method .action_methods and exclude from it all actions for whom you need a specific route:
scope '/', controller: :static_pages do
(StaticPagesController.action_methods.to_a - ["home_page", "secret"])
.each do |action_method|
get action_method
end
end

Rails can't find Path

So, I have the following code. I want to access timespans_path,
but I can't.
<% content_for :div_header do%>
<h1> Welcome, <%= #l_user.name %> </h1>
<% end %>
<% content_for :div_sub_header do %>
<ul>
<li><%= link_to "show entries", entries_path %></li>
<li><%= link_to "show groups", groups_path %>
<% if can? :read, Subgroup %>
,
<%= link_to " subgroups", subgroups_path %>
</li>
<% end %>
<li><%= link_to "show users", users_path %></li>
<li><%= link_to "show actioncodes", actioncodes_path %></li>
<li><%= link_to "show timespans", timespans_path %></li>
</ul>
<% end %>
I always get these errors:
NameError in Application#welcome
Showing C:/xampp/htdocs/fluxcapacitor/app/views/application/welcome.html.erb where line #16 raised:
undefined local variable or method `timespans_path' for #<#<Class:0x58b8610>:0x58b7e18>
This is my route.rb:
Fluxcapacitor::Application.routes.draw do
root 'application#welcome'
get 'login' => 'application#login'
post 'login' => 'application#process_login'
post '' => 'application#process_login'
post 'send_request_account_mail' => 'application#send_request_account_mail'
post 'send_forgot_password_mail' => 'application#send_forgot_password_mail'
get 'forgot_password' => 'application#forgot_password'
get 'request_account' => 'application#request_account'
get 'welcome' => 'application#welcome'
get 'logout' => 'application#logout'
if Rails.env.development?
get 'display_mail' => 'application#display_mail'
end
resources :users
get 'multiple_new' => 'users#multiple_new'
post 'multiple_new' => 'users#multiple_new'
post 'multiple_create' => 'users#multiple_create'
get 'users/:id/:hash/cal' => 'users#cal'
resources :actioncodes
resources :entries
resources :timespans
resources :groups do
member do
get 'search_admin'
post 'search_admin'
post 'add_admin'
get 'remove_admin'
post 'remove_admin'
end
end
resources :subgroups do
member do
get 'search_user'
post 'search_user'
post 'add_user'
get 'remove_user'
post 'remove_user'
get 'remove_admin'
post 'remove_admin'
end
end
end
Why am I getting the error? How can I fix it?
Add
resources :timespans
in your route.rb
It looks like you haven't defined a path called timespans, so the view doesn't know what URL to render and is raising an error.
If you have a model called Timespan then adding resources :timespans to your routes file will create a path called timespans_path (among others), pointing to /timespans.
You can also create any arbitrary path called timespans path using the :as option, e.g.:
get "/the_url", to: "the_controller#the_action", as: :timespans
If you have problems with paths in the future, note that you can use the rake task rake routes to list all your generated routes and the names of their path helpers, which can be very helpful for debugging.

Trouble showing articles on Ruby on Rails?

I created a form to create articles, but I can only see the published articles on the index page, and, I'm unable to see individual articles.
Every time I click on 'show' for an individual article on the index, it opens a blank page with a URL like localhost:3000/articles.1, instead of localhost:3000/articles/1.
I don't know what's wrong with the code, it's similar to the code I have for creating and editing articles as admin and it works there, but I keep getting this error.
Here's the code:
views/articles/show.html.erb:
<h1><%= #article.name %></h1>
<%= #article.content %>
<%= image_tag #article.photo.url(:small) %>
<p>Tags: <%= raw article.tag_list.map { |t| link_to t, tag_path(t) }.join(', ') %></p>
<%= link_to 'Back', noticias_path %>
views/articles/index.html.erb:
<% #articles.each do |article| %>
<div>
<h2><%= article.name %></h2>
<%= article.content %>
<p><%= link_to 'Show', noticias_path(article) %></p>
<p>Tags: <%= raw article.tag_list.map { |t| link_to t, tag_path(t) }.join(', ') %></p>
</div>
<% end %>
articles_controller.rb:
# GET /articles/1
# GET /articles/1.json
def show
#article = Article.find(params[:id])
end
routes.rb:
Blog::Application.routes.draw do
root to: 'welcome#index'
get 'tags/:tag', to: 'noticias#index', as: :tag
get "noticias/index"
get "dashboard/index"
get "/sitemap" => "sitemap#index", :as => :sitemap, :defaults => {:format => :xml}
match '/noticias', to: 'noticias#index', via: 'get'
get 'login', to: 'sessions#new', as: 'login'
get 'logout', to: 'sessions#destroy', as: 'logout'
resources :users
resources :sessions
namespace :admin do
get '', to: 'dashboard#index', as: '/'
resources :noticias
end
end
It's more a problem with noticias_path, consider verify your routes with rake routes, but I think to change noticias_path to noticia_path, may can fixed it.
Based on your routes file, it looks like the problem is indeed incorrect routing. Presently, you are manually creating routes for RESTful resources, when you should simply let rails handle that for you properly.
Remove the manual get and match lines:
get "noticias/index"
match '/noticias', to: 'noticias#index', via: 'get'
And replace them with this:
resources :noticias
If noticias should be pointing to the ArticlesController (or any other controller), then simply do this:
resources :noticias, to: 'articles'
Also, Matheus Caceres was correct that the URL helper should in fact be noticia_path for the show action. The noticias_path points to the index action. Rails tries to be "helpful" by making routes, helpers, functions, etc, sound proper if read in English, but might not necessarily make sense for words in another language. I don't know if "noticia" makes any sense in Portuguese though.
Another quick side note, the two manual routing lines I indicated above are redundant; they would in fact both match a GET request and route them to noticias#index. However, keep in mind that routes are matched in the order they appear in the routing file, so the match line would never have been called, since the route would have matched on that get line.

Strange Routing error in rails 3. Rails changes the route that is specified

I have a rails 3 app, and when I click the link to my terms page, it routes to a completely different controller, than what the routes should use. Stranger still, the route works when I'm not logged in, and I'm using devise.
I get this error when clicking the link when I'm logged in.
No route matches {:action=>"edit", :controller=>"users", :id=>nil}
<%= link_to "Terms", terms_path %>
Routes (in the order they appear in routes.rb):
devise_for :users, :controllers => {:registrations => "registrations"}
resources :users do
member do
get :following, :followers
post :accept
end
end
match '/terms', to: 'static_pages#user_agreement'
Static Pages Controller
def user_agreement
end
Rake Routes
terms /terms(.:format) static_pages#user_agreement
This also happens for every other action that I've routed this way to the staticpages controller, but not for any other actions that route to different controller.
Update: Terms Page
Header:
<%= link_to "Follow", users_path %>
<%= link_to current_user.name, current_user %>
<%= link_to "Sign out", destroy_user_session_path, :method => :delete %>
Footer:
<%= link_to "Welcome", welcome_path %>
<%= link_to "Settings", edit_user_path(#user) %>
<%= link_to "Terms", terms_path %>
All the content is pure html.
Thanks in advance
You have a link to edit_user_path with no #user as hinted in the comments.
You should almost certainly be using current_user anyway.

Rails renders wrong URL with nested resources

I'm not really sure what going on here. After nesting the resources like this
resources :users do
resources :bookmarks
end
I expected the url should be /users/[user-id]/bookmarks/[bookmark-id]/edit, but rails renders a reverse path /users/[bookmark-id]/bookmarks/[user-id]/edit
This is the view
<%= link_to 'edit', edit_user_bookmark_path(#bookmark) %>
Any idea how to fix it ? Thanks
What you expect is the rule.
Replace with:
<%= link_to 'edit', edit_user_bookmark_path(current_user, #bookmark) %>

Resources