Rails custom action not working due to show, how to fix? - ruby-on-rails

I'm trying to create a customer action in my campaigns controller called building.
http://localhost:3000/campaigns/building
Shows error:
Showing .../app/views/campaigns/show.html.erb where line #1 raised:
undefined method `name' for nil:NilClass
<h2><%= #campaign.name %></h2>
<p>
Created by: <%= #campaign.user.email %> <%= time_ago_in_words(#campaign.created_at) %> ago.
</p>
<h5>Website: <%= #campaign.website %></h5>
My routes file:
resources :campaigns do
resources :targets
end
get "campaigns/building" => "campaigns#building", :as => :campaigns_building
Controller:
class CampaignsController < ApplicationController
before_action :find_campaign, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!
def show
end
def building
end
...
My show.html.erb:
<h2><%= #campaign.name %></h2>
<p>
Created by: <%= #campaign.user.email %> <%= time_ago_in_words(#campaign.created_at) %> ago.
</p>
<h5>Website: <%= #campaign.website %></h5>
How do I make it not give this error?

It seems you are trying to make a custom route and unable to make it work. If so, to make it work, you should move your custom route above resources to avoid conflicts with the default resourceful route and correctly route to building action
get "campaigns/building" => "campaigns#building", :as => :campaigns_building
resources :campaigns do
resources :targets
end
This is because Rails tries to match routes starting from the top down. You can also define it as a collection route on the resources
resources :campaigns do
get "building", on: :collection
resources :targets
end

Related

undefined method contact_path in rails form

I have my routes defined as below
get 'contacts/new', to: 'contacts#new'
And in my ContactsController I have defined as below
def new
#contact = Contact.new
end
In views contacts/new/_form.html.erb I have structured form as below
<%= form_for #contact, html: {multipart:true} do |f| %>
<%= f.label :username %>
<%= f.text_field :username %>
<% end %>
But when i go to localhost:3000/contacts/new
I get the below error.
undefined method contacts_path which is occuring in first line of form.
But when i try to define as below in routes, it worked
get 'contacts/new', to: 'contacts#new', as: 'contact'
Any idea why rails throws such error when i have defined it in the routes file. I am just trying to understand inner workings of rails routes
To avoid this kind of errors, remove your route and use:
resources :contacts, only: [:new, :create]
Try better use railsy way like resources as #Graham mentioned.
or
get 'contacts', to: 'contacts#index', as: :contacts #genetares: contacts_path
get 'contacts/new', to: 'contacts#new', as: :new_contact #new_contact_path
Make a post type route for contacts (for this it is throwing error)
Or remove this route
get 'contacts/new', to: 'contacts#new'
And add this simply
resources :contacts

No route matches [PUT] but I included "resources" in routes.rb

I'm coding a blog that has two types of articles: "drafts" and "published". I'm using the aasm gem for making the article transition from draft to published or viceverza. There are also three types of users: "regular readers", "editors" and "admins".
As users write articles, admins can evaluate whether to publish them or not. To accomplish this, admins have a view in which they can see both drafts and published articles.
The problem is that when I try to publish the articles I get the No route matches [PUT] "/articles" error, regardless I've added resources :articles in routes.rb.
The code I wrote is the following:
routes.rb
resources :categories
resources :articles do
resources :comments, only: [:create, :update, :destroy, :show]
end
devise_for :users
root 'welcome#index'
get '/dashboard', to: 'welcome#dashboard'
put '/articles/:id/publish', to: 'articles#publish'
articles_controller.rb
...
def publish
#article.publish! # Article transition from draft to published.
redirect_to #article
end
...
dashboard.html.erb
...
<% #articles.each do |art| %>
<h1><%= link_to art.title, art, method: :get %> | id = <%= art.id %> | user_id = <%= art.user_id %></h1>
<div>
<%= art.body %> - <%= link_to "Eliminar", art, method: :delete %>
<% if art.may_publish? %>
- <%= link_to "Publicar", '/articles/#{article.id}/publish' , method: :put %>
<% end %>
</div>
<% end %>
...
I can't see why I get this error if I included the article resource. If you need me to include more code don't hesitate to ask me.
Thanks in advanced.
You should remove your custom routes and put it into resources :articles like this :
routes.rb
resources :articles do
put 'publish', on: :member
resources :comments, only: [:create, :update, :destroy, :show]
end
and you should use this in your view :
<%= button_to "Publicar", publish_article_path(article), method: :put %>
It will generate a form.
The code seems to be correct, so try to reset the server and, by the way, restart the browser. It usually solves strange problems like this :) Let me know if it worked.

undefined method `post_up_vote_path'

I am trying to come up with upvote/downvote method in my app and I running into a no method error.
Here is my voter form:
<div>
<div class= 'pull-left'>
<div><%= link_to " ", post_up_vote_path(post), class: 'glyphicon plyphicon-chevron-up', method: :post %></div>
<div><strong><%= post.points %></strong></div>
<div><%= link_to " ", post_down_vote_path(post), class: 'glyphicon plyphicon-chevron-up', method: :post %></div>
</div>
Here are my routes:
App::Application.routes.draw do
devise_for :users
resources :users
resources :topics do
resources :posts, except: [:index] do
resources :comments, only: [:create, :destroy]
post '/up-vote' => 'votes#post_up_vote', as: :up_vote
post '/down-vote' => 'votes#post_down_vote', as: :down_vote
end
end
get 'about' => 'welcome#about'
root to: 'welcome#index'
end
And here is my partial call:
<%= render partial: 'votes/voter', locals: { post: post } %>
Now I don't think there is anything wrong with my partial call or my voter partial because everything works until I try to route it.
First, you will need to change up your routes a bit.
resources :posts, except: [:index] do
resources :comments, only: [:create, :destroy]
post 'upvote', on: :member
post 'downvote', on: :member
end
The reason these are member routes instead of collection routes is being they apply to a specific member of the collection of posts...a single Post.
Then, you will want to run the command, rake routes in your Terminal to see what the appropriate path methods are. It should be something like
upvote_post_path(:id)
which requires an object be passed in..so in your view you would use it like you currently are.
upvote_post_path(post)

Rails nesting from the CoreController. Troubles with routing

I have some user types such as Student, Teacher, Admin. For each user type I have a controller. For instance student controllers placed in the app/controllers/students directory. But mostly controllers are the same. Because of this I created core controllers placed in the app/controllers/core.
app/controllers/core/settings_controller.rb
class Core::SettingsController < ApplicationController
def show
# instance variables, redirections etc. placed here...
#
end
# other actions...
#
end
app/controllers/student/settings_controller.rb
class Student::SettingsController < Core::SettingsController
end
routes.rb
namespace :student do
# ...
resource :schedule, :only => [:show]
resource :settings, :only => [:show, :update]
end
namespace :admin do
# ...
resource :settings, :only => [:show, :update]
end
Problems started when I added <%= link_to "<", schedule_path(:date => #date.prev_month)" %> to my views/core/settings/_month_nav.html.erb file.
Is there any solution except writing this ugly peaces of code:
<% if admin? %>
<%= link_to "<", admin_schedule_path ... %>
<% elsif student? %>
<%= link_to "<", student_schedule_path ... %>
...
You could do something like
<%= link_to "<", self.send("#{current_user.class.to_s.downcase}_schedule_path",:date => #date.prev_month) %>
I used current_user because I am not sure how you are setting this as your view code was not very clear.

Polymorphic Paths for Custom Routes?

<%= collection.each do |record| %>
<%= link_to record.name, polymorphic_path([:admin, record]) %>
<% end %>
Breaks with this route:
resources :users, as: "authors", path: "authors", except: [:create, :destroy]
Error:
undefined method `admin_user_path'
Can anyone help?
I've got it as a Rails bug
You should also define users resource inside admin namespace
namespace :admin do
resources :users
end

Resources