Thumbs up gem routing error - ruby-on-rails

I seek clarification on using the thumbs up gem with rails 4. I current have a user resource and a post resource and have set up thumbs up as follows.
add gem to gemfile and installed it using bundler.
Generated require migration
User model
class User < ActiveRecord::Base
acts_as_voter
end
Post model
class Post < ActiveRecord::Base
acts_as_voteable
end
Post controller
def vote_up
#post = Post.find(params[:id])
current_user.vote_for(#post)
respond_to do |format|
format.js
end
end
View
<%= link_to('vote for this post!', vote_up_post_path(#post) , :method => :post) %>
Route file
resources :posts do
member do
post :vote_up
end
end
However i keep getting this error
No route matches [POST] "/posts/vote_up"
And after running rake routes I can see that the following route is available to me:
vote_up_post POST /posts/:id/vote_up(.:format) posts#vote_up
any ideas what could be the cause of this error ?

Could you please show us your view.
Apparently, you are calling
/posts/vote_up
instead of
/posts/:id/vote_up

"vote_up" acts like a RESTful action, similar to "post/1/delete", "post/1/edit". So you need to add this custom RESTful action in route.
Change your route like this at first.
resources :posts do
member do
post 'vote_up'
end
end
Then, in your view, to use this path, add resource as arg
vote_up_post_path #post
Reference: http://guides.rubyonrails.org/routing.html#adding-more-restful-actions

Other people reading this notes should realise that post is not a singluar of his controller posts... but the post http verb
resources :contenders do
member do
post 'vote_up'
end
end

Not sure but in your view, instead of #post try giving #post.id to vote_up_post_path.
<%= link_to('vote for this post!', vote_up_post_path(#post.id) , :method => :post) %>

Related

Routing error for rails - uninitialized constant SubscribersController

I have a Subscriber model that takes in a "phone_number" and a "visit" integer. I have two controllers Subscribers and Visits(super and sub) I have never worked with nested controllers before and I'm having some issues with namespace I believe. Because I getting back the uninitialized constant error. Basically the subscriber controller signs up a subscriber and the visit controller counts the amount of times they've visited by user input of their phone_number. Why am I getting this error? I'll show my code for clarity.
CONTROLLERS
class Subscribers::VisitsController < ApplicationController
def new
#subscriber = Subscriber.new
end
def create
#subscriber = Subscriber.find_by_phone_number(params[:phone_number])
if #subscriber
#subscriber.visit += 1
#subscriber.save
redirect_to subscribers_visits_new_path(:subscriber)
else
render "new"
end
end
end
class SubscribersController < ApplicationController
def index
#subscriber = Subscriber.all
end
def new
#subscriber = Subscriber.new
end
def create
#subscriber = Subscriber.create(subscriber_params)
if #subscriber.save
flash[:success] = "Subscriber Has Been successfully Created"
redirect_to new_subscriber_path(:subscriber)
else
render "new"
end
end
ROUTES
Rails.application.routes.draw do
devise_for :users
resources :subscribers, except: :show
get '/subscribers/visits/new', to: 'subscribers/visits#new'
root "welcomes#index"
VIEWS
<h1>hey</hey>
<%= form_for #subscriber do |form| %>
<div class="form-group">
<p>
<%= form.label :phone_number %>
<%= form.text_field :phone_number %>
</p>
<% end %>
ERROR
Hmm, my guess is you are trying to route url subscriber/visits/new to new action in VisitsController?How about changing this line:
get '/subscribers/visits/new', to: 'subscribers/visits#new'
to:
namespace :subscribers do
get '/visits/new', to: 'visits#new'
end
Also try to move this block above resources :subscribers, except: :show if you still get the error.
Cheers
You probably do not need to inherit one controller from another. Simply define the controllers as you normally would:
app/controllers/subscribers_controller.rb
class SubscribersController < ApplicationController
# methods for Subscribers
end
in app/controllers/visits_controller.rb
class VisitsController < ApplicationController
# methods for Visits
end
Note that these must to be located in separate files, so that Rails can find the correct source file by the name of the object that it's looking for. This is a Rails naming convention.
Regarding your routes, you'll need to change to use one of 4 route formats. Reading the section on Adding More RESTful Actions in the Rails Routing from the Outside In guide might help.
1) To route visits as a nested resource, which is what it appears you're actually trying to do, you would use this:
resources :subscribers, except: :show do
resources :visits
end
This will produce these routes:
GET /subscribers/new
POST /subscribers
GET /subscribers
GET /subscribers/:id/edit
PATCH /subscribers/:id/update
DELETE /subscribers/:id/destroy
GET /subscribers/:id/visits/new
POST /subscribers/:id/visits
GET /subscribers/:id/visits
GET /subscribers/:id/visits/:id
GET /subscribers/:id/visits/:id/edit
PATCH /subscribers/:id/visits/:id/update
DELETE /subscribers/:id/visits/:id/destroy
This is the typical route structure for nested resources and separate controllers.
2) To make visits#new a simple collection (non-member) action in the VisitsController, then you likely want this:
resources :subscribers, except: :show do
collection do
get 'visits/new', to 'visits#new'
post 'visits', to 'visits#create'
end
end
This will produce these routes:
GET /subscribers/new
POST /subscribers
GET /subscribers
GET /subscribers/:id/edit
PATCH /subscribers/:id/update
DELETE /subscribers/:id/destroy
GET /subscribers/visits/new
POST /subscribers/visits
This is typically used to add new top-level routes in an existing resource and controller.
3) To construct visits as member actions, use this:
resources :subscribers, except: :show do
member do
get 'visits/new', to 'visits#new'
post 'visits', to 'visits#create'
end
end
This will produce these routes:
GET /subscribers/new
POST /subscribers
GET /subscribers
GET /subscribers/:id/edit
PATCH /subscribers/:id/update
DELETE /subscribers/:id/destroy
GET /subscribers/:id/visits/new
POST /subscribers/:id/visits
This is normally used to add new member routes in an existing resource and controller.
4) To simply make visits routes appear to be included in subscribers, you could use this:
get '/subscribers/visits/new', to: 'visits#new'
post '/subscribers/visits', to: 'visits#create'
resources :subscribers, except: :show
This will produce these routes:
GET /subscribers/visits/new
POST /subscribers/visits
GET /subscribers/new
POST /subscribers
GET /subscribers
GET /subscribers/:id/edit
PATCH /subscribers/:id/update
DELETE /subscribers/:id/destroy
This may be used to make arbitrary routes appear to be included in an existing resource, when they really may be independent.

Rails routing error when routing to slug

I have a the following link that goes to the correct page i.e. /events/tech/schedule but I get a routing error.
<%= link_to "View Schedule", event_sessions_path(#event.slug) %>
Error
ActionController::RoutingError at /events/tech/schedule
Not Found
Routes
resources :events do
resources :sessions, path: "schedule", only: [:index]
end
Sessions Controller
before_filter :find_event
private
def find_event
#event = Event.find_by(slug: params[:id])
##event = Event.find(params[:event_id]) This works if I use <%= link_to event_sessions_path(#event.id) %>
end
I don't get any error if I use the event id to link to but this looks ugly and isnt a very good solution.
Edit - add rake routes
event_sessions GET /events/:event_id/schedule(.:format) sessions#index
Here's your solution:
#event = Event.find_by(slug: params[:event_id])
When using resourceful routes in the structure you have, you'll end up wtih this:
events/:event_id/schedule #-> to schedules#index with params[:event_id]
The name of the variable doesn't matter - it's the content which does. :event_id can hold anything (id or slug), what matters is how you deal with it in the controller
If you change your Event.find_by method to use the event_id param, you'll be able to find what you need
friendly_id
A better way to handle this is with friendly_id
If you use the finders module in friendly_id, you'll be able to search either id or slug like this:
Event.find params[:event_id]

Rails - Routing Error for the POST method

Rails newbie here (trying to get these questions answered)
I'm using Ryan Bates' Rails Cast on Wicked Wizard Forms to create a multi-step form. I'm getting a "No route matches [POST] "/user_steps/gender" (where gender is a view under the user_steps controller).
Any ideas?
routes.rb:
Store::Application.routes.draw do
resources :likes
resources :categories
resources :users
resources :user_steps
root to: 'static_pages#home'
user_steps controller:
class UserStepsController < ApplicationController
include Wicked::Wizard
steps :gender, :items, :brands, :final
def show
render_wizard
end
def update
#user.attributes = params[:user]
render_wizard
end
end
When you define a new method, rails will default to a get request on that method. In order to make it a post method, try adding
match "user_steps/gender", to: "user_steps#gender", via: "post"
Check out this routes reference
I'm looking for rails wizards solutions and was going through "#346 Wizard Forms with Wicked" railscas when I ran into the same issue.
Adding a route, as #Klipfel suggests, is a good "rails" answer but not the correct approach for the wicked gem. If you add a route pointing to another controller method you are routing the request outside of the wicked framework.
I resolved this problem by specifying put for the http method. In the #346 Wizard Forms with Wicked railscast case it would look like this:
<%= form_for #user, url: wizard_path, method: :put do |f| %>
I'm not sure why it works in the railscast

Routing Error - custom controller

I have a has many through association.
Firms have many Users through Follows.
I want Users to be able to Follow Firms. - I am using Devise for the users.
I have the following action in my firms controller.
def follow
#firm.users << current_user
end
in my routes.rb
resources :firms do
post :follow, on: :member
end
and in my firms view
<%= link_to "Follow", follow_firm_path(#firm), method: :post %>
However when I keep getting the following Routing Error in the browser
No route matches {:action=>"follow", :controller=>"firms"}
Rake Routes confirms the following
follow_firm POST /firms/:id/follow(.:format) firms#follow
Any ideas what the problem may be?
Many thanks
Edit: Controller code
class FirmsController < ApplicationController
before_filter :authenticate_user!, :except => [:show, :index]
def index
#firm_names = Firm.all.map &:name
direction = params[:direction]
direction ||= "ASC"
#firms = Firm.order("name #{direction}")
respond_to do |format|
format.html # index.html.erb
format.js
end
end
def follow
#firm.users << current_user
end
I am using the follow action in a partial in the index view.
everything looks good and this should work perfectly. Except that I see a typo in the following line
<%= link_to "Follow", follow_firm_path(#firm), method: :post %>
after the :method there should an => not a : . this will make the link a get request not a post request, that might be the issue, try using a simple link and replace post will get in your routes.rb just to test if the issue is arising due to this.
you can also test route methods from the console
rails c
app.follow_firm_path(2)
I noticed you also have an error in your routes, there should be an => not a : after :on
resources :firms do
post :follow, :on => member
end
You should define methods like this...
resources :firms do
collection
post :follow, on: :member
end
end
I think if this method does not create anything its type should be get.
Try it

Link to resource

I have created model, view and controller:
$ rails generate scaffold Post name:string title:string content:text
I run server and I see list of posts if I open in the browser http:\localhost:3000\posts.
Now I need to create link to this page. Something like:
<%= link_to("settings", { :controller => 'groups', :action => 'index'}) %>
But I get error on opening this page:
Couldn't find Group with ID=index
How ca I create link to http:\localhost:3000\posts and which action do I use in this case?
I think the path helpers are excellent in these cases. You could do it like this:
<%= link_to("Posts", posts_path) %>
posts_path in this case will link to http://localhost:3000/posts
When you use use resources :posts in your routes.rb you automatically get a few path helpers. For example:
posts_path # /posts
post_path(#post) # /posts/1
edit_post_path(#post) # /posts/1/edit
new_post_path # /posts/new
If you have a route such as:
resources :groups
In config/routes.rb then you will have the helper groups_path. You can use rake routes to see all of your routes and helpers, but in this case you will have:
groups_path
group_path(#group)
edit_group_path(#group)
Polymorphic Routes Documentation

Resources