I'm receiving the following error in my Rails app when I try to access a page that contains a form to create a post. I'm trying to implement a feature similar to Michael Hartl's Micropost feature in his sample app:
NoMethodError in Home#index
undefined method `posts_path' for #<#<Class:0xb5c70744>:0xb60013b8>
Here's the index view page that contains the code to insert the form:
<%= render 'shared/post_form' if user_signed_in? %>
_post_form.html.erb:
<%= form_for(#post) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.text_area :content, placeholder: "Provide your network with a status update..." %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
Here is the Home controller:
class HomeController < ApplicationController
before_filter :authenticate_user!
def index
#render :text => "Welcome #{current_user.email}!"
#users = User.all
#post = current_user.posts.build if signed_in?
end
end
I can really use some help in reviewing the code. I'm staring at it and I need someone else to review it for me. I'm new to Rails so please forgive me if I did not provide the necessary information.
Additional information: I'm using the Devise gem to handle user authentication.
Thanks!
EDIT: I added the wrong controller.
EDIT 2:
Routes.rb file:
AppName::Application.routes.draw do
#get "users/index"
#get "users/show"
authenticated :user do
root :to => 'home#index'
end
root :to => "home#index"
devise_for :users
resources :users do
member do
get :following, :followers, :posts
end
end
resources :works
resources :relationships, only: [:create, :destroy]
end
EDIT 3: Rake routes
root / home#index
root / home#index
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
following_user GET /users/:id/following(.:format) users#following
followers_user GET /users/:id/followers(.:format) users#followers
posts_user GET /users/:id/posts(.:format) users#posts
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
works GET /works(.:format) works#index
POST /works(.:format) works#create
new_work GET /works/new(.:format) works#new
edit_work GET /works/:id/edit(.:format) works#edit
work GET /works/:id(.:format) works#show
PUT /works/:id(.:format) works#update
DELETE /works/:id(.:format) works#destroy
relationships POST /relationships(.:format) relationships#create
relationship DELETE /relationships/:id(.:format) relationships#destroy
You need to add resources :posts in your routes.rb file in order for Rails to automatically create the posts_path helper for you.
Adding resources :posts will generate the proper RESTful routes for you to create, delete, update, and fetch posts. Take a look at the Ruby on Rails Guide for routing, specifically this section here on routing and RESTful routes.
Related
I am learning ruby on rails by making a project web app,
whenever i go to <%= link_to 'My Profile', user_path(:id) %> error Couldn't find User with 'id'=id" is shown...and url is "http://localhost:3000/users/id
If i convert above link to <%= link_to 'My Profile', user_path %>, it works but now all other pages except user's show page give error No route matches {:action=>"show", :controller=>"users"} missing required keys: [:id]....I cant seem to find any solution anywhere...
Here are my configs:
rake routes Prefix Verb URI Pattern Controller#Action
root GET / static#landing
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
user_confirmation POST /users/confirmation(.:format) devise/confirmations#create
new_user_confirmation GET /users/confirmation/new(.:format) devise/confirmations#new
GET /users/confirmation(.:format) devise/confirmations#show
user GET /users/:id(.:format) users#show
_header.html.erb
<%= link_to 'My Profile', user_path %>
users_controller.rb
class UsersController < ApplicationController
def show
#user = User.find(params[:id])
end
end
routes.rb
Rails.application.routes.draw do
root 'static#landing'
devise_for :users
resources :users, :only => [:show]
You need to pass the id of a user to user_path, not the symbol :id - so something like
<%= link_to 'My Profile', user_path(#current_user.id) %>
if the user you want to link to is in an instance variable - or since you are using Devise and it provides the current_user helper you might be wanting
<%= link_to 'My Profile', user_path(current_user.id) %>
I think the first thing wrong is this:
<%= link_to 'My Profile', user_path(:id) %>
You are using a symbol, not a variable
<%= link_to 'My Profile', user_path(#id) %>
Would have an actual variable, assuming you have set #id in your controller.
Normally however you would not set the id for a user in a path - it's a recipe for someone to just change the number manually and view someone elses.
Lets assume you set a session variable called :user_id, then you should do something adding a collection route - so no id is sent.
resources :users do
get :show_profile, on: :collection
end
This gets you a path to your show_profile action, called with
link_to 'My Profile', show_profile_user_path
Then in your controller do your user look up from the session - so something like:
#user = User.find_by id: session[:user_id]
I don't know how devises does things, but please don't trust a user to not fiddle with your parameters!
I am relatively new to Rails and I encountered what seems to be a common problem but after reading through all the responses, I cannot seem to make any work for my situation.
I have an app that keeps track of loans and users, and am trying to add a payment feature. When I try to reach the payment page I encounter this TypeError: no implicit conversion of Symbol into String. I have tried a bunch of things but nothing seems to work. I'm not sure if its how I am trying to access the loan_id or something else.
The error is encountered in PaymentsController#create
Here is my view:
show.html.erb
<p id="notice"><%= notice %></p>
<div class="row">
<div class="col-md-2">
<ul>
<li><strong>Lender</strong>: <%= #loan.lender.username %></li>
<li><strong>Borrower</strong>: <%= #loan.borrower.username %></li>
<li><strong>Amount Remaining</strong>: <%= #loan.amount %></li>
<li><%= link_to "New Payment", loan_payments_path(#loan.id), :method => :post %></li>
</ul>
<section>
</section>
</div>
</div>
<%= link_to 'Edit', edit_loan_path(#loan) %> |
<%= link_to 'Back', loans_path %>
app/controllers/payments_controller
class PaymentsController < ApplicationController
# POST /loans/:loan_id/payments
def create
#loan = Loan.find(params[:loan_id])
#loan.make_payment(payment)
if #load.save
redirect_to #loan, notice: "Payment successful"
else
redirect_to #loan, alert: "Payment count not be processed"
end
end
private
def payment
require(:loan).require(:payment)[:payment]
end
end
routes
Rails.application.routes.draw do
devise_for :users
resources :users, only: [:index, :show]
resources :loans, shallow: :true do
resources :payments, only: :create
end
root 'static_pages#home'
end
Prefix Verb URI Pattern Controller#Action
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
users GET /users(.:format) users#index
user GET /users/:id(.:format) users#show
loan_payments POST /loans/:loan_id/payments(.:format) payments#create
loans GET /loans(.:format) loans#index
POST /loans(.:format) loans#create
new_loan GET /loans/new(.:format) loans#new
edit_loan GET /loans/:id/edit(.:format) loans#edit
loan GET /loans/:id(.:format) loans#show
PATCH /loans/:id(.:format) loans#update
PUT /loans/:id(.:format) loans#update
DELETE /loans/:id(.:format) loans#destroy
root GET / static_pages#home
Parameters
{"_method"=>"post",
"authenticity_token"=>"VI7rp4N2eHw+tPkY2noD/so9vnGKy/ue06052Vj1f4qidNzgDjZT3aV5v8+XZMs2ZqiUWE0xzAMSQPWltfT6lg==",
"loan_id"=>"5"}
Your problem in this method:
def payment
require(:loan).permit(:payment)[:payment]
end
Fix it to:
def payment
params.permit(:loan_id)
end
Read how to permit params in Rails.
Update:
Now I get the error ActionController::ParameterMissing in
PaymentsController#create param is missing or the value is empty:
loan
this is normal behavior, because your parameters is empty, you sent nothing to the action, except a load_id, to send the params with #load attributes, pass it to the loan_payments_path() helper, like:
<li><%= link_to "New Payment", loan_payments_path(#loan.id, params: { loan_amount: #loan.amount }), :method => :post %></li>
And permit it in controller code:
def payment
params.permit(:loan_id, :loan_amount)
end
I'm new to RoR and Devise and i'm stuck in User Authentications with Devise. I'm developing a web site, which has admin pages in it. My structure looks like this:
app
|-controllers
|-admin
|- user_list_controller.rb //Every user crud operations are in it.
|-views
|-admin
|-user_list
|-new.html.erb
|-edit.html.erb
|-devise //Also have devise views
UserListController:
class Admin::UserListController < ApplicationController
layout 'admin/admin'
def index
#user_list = User.all
end
def new
#user = User.new
end
def edit
end
def delete
end
def create_user
end
end
What I want to do is that, I want to use Devise methods under this controller but this is where I stuck in. I created a UserController which base is Devise::RegistrationsController. But this time I got this error,
Could not find devise mapping for path "/admin/create_user". This may
happen for two reasons: 1) You forgot to wrap your route inside the
scope block. For example: devise_scope :user do get "/some/route" =>
"some_devise_controller" end 2) You are testing a Devise controller
bypassing the router. If so, you can explicitly tell Devise which
mapping to use: #request.env["devise.mapping"] =
Devise.mappings[:user]
It looks like a route.rb error and my route file is:
Rails.application.routes.draw do
devise_for :users
devise_scope :user do
# post "admin/add_user" =>"admin/user_list#create_user", as: :adduser
end
namespace :admin do
root to: 'admin#index'
get 'user_list', :to => 'user_list#index'
post 'create_user', :to => "user#create"
get 'new_user', :to => 'user_list#new'
get 'user_proposals', :to => 'user_proposal_forms#index'
get 'user_appointments', :to => 'user_appointments#index'
get 'brands', :to => 'brands#index'
get 'brand_makes', :to => 'brand_makes#index'
get 'make_types', :to => 'make_types#index'
end
end
And the result of rake routes is this:
Prefix Verb URI Pattern Controller#Action new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format)devise/registrations#new edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
admin_root GET /admin(.:format) admin/admin#index
admin_user_list GET /admin/user_list(.:format) admin/user_list#index
admin_create_user POST /admin/create_user(.:format) admin/user#create
admin_new_user GET /admin/new_user(.:format) admin/user_list#new
admin_user_proposalsGET /admin/user_proposals(.:format) admin/user_proposal_forms#index
admin_user_appointments GET /admin/user_appointments(.:format) admin/user_appointments#index
admin_brands GET /admin/brands(.:format) admin/brands#index
admin_brand_makes GET /admin/brand_makes(.:format) admin/brand_makes#index
admin_make_types GET /admin/make_types(.:format) admin/make_types#index
It looks messy, sorry for that. Finally my form_for looks like this:
<%= simple_form_for #user, url: admin_create_user_path, class: "form-horizontal" do |f| %>
<%= render(:partial => "form", :locals => {:f => f}) %>
<% end %>
So where did I make a mistake? I've read all the documents in Devise, tried so many things but couldn't solve the problem.
In routes file use
devise_for :users, :controllers => { registrations: 'registrations' }
I'm building a web app that uses devise. Upon signup with :email, :password, and :password confirmation, the new user is redirected to a second form where they will enter social information (such as hobbies, age, location, etc...) right now the form only contains fields for first and last name.
After submitting the second form, the user should be redirected back to the users#index page which is also where users who are signing in are redirected to. I just created the second form, and after submitting I get the following error:
No route matches [POST] "/users/user/edit_profile"
Below are the relevant files. I'm pretty new, does anyone have any ideas about this?
routes.rb
Appname::Application.routes.draw do
devise_for :users, :controllers => { :registrations => "registrations" }
devise_scope :user do
get 'register', to: 'devise/registrations#new'
get 'login', to: 'devise/sessions#new', as: :login
get 'logout', to: 'devise/sessions#destroy', as: :logout
end
resources :users do
member do
get 'edit_profile'
end
end
root to: "home#index"
match '/about', to: 'static_pages#about', via: 'get'
match '/contact', to: 'static_pages#contact', via: 'get'
match '/help', to: 'static_pages#help', via: 'get'
match '/legal', to: 'static_pages#legal', via: 'get'
end
users_controller.rb
class UsersController < ApplicationController
before_filter :authenticate_user!
def index
#users = User.all
end
def show
#user = User.find(params[:id])
end
def new
end
def create
end
def edit
end
def update
#user = User.find(params[:id])
#user.update!(user_params)
redirect_to #user
end
def destroy
end
def edit_profile_user
#user = User.find(params[:id])
redirect_to #user
end
def user_params
params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation, :hobbies)
end
end
edit_profile.html.erb
<h2>Tell us about yourself</h2>
<%= form_for(resource, as: resource_name, url: edit_profile_user_path(resource_name)) do |f| %>
<%= f.label :first_name %><br />
<%= f.text_field :first_name, autofocus: true %>
<%= f.label :last_name %><br />
<%= f.text_field :last_name %>
<div><%= f.submit "Update" %></div>
<% end %>
here are my rake routes:
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) registrations#cancel
user_registration POST /users(.:format) registrations#create
new_user_registration GET /users/sign_up(.:format) registrations#new
edit_user_registration GET /users/edit(.:format) registrations#edit
PATCH /users(.:format) registrations#update
PUT /users(.:format) registrations#update
DELETE /users(.:format) registrations#destroy
register GET /register(.:format) devise/registrations#new
login GET /login(.:format) devise/sessions#new
logout GET /logout(.:format) devise/sessions#destroy
edit_profile_user GET /users/:id/edit_profile(.:format) users#edit_profile
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
root GET / home#index
about GET /about(.:format) static_pages#about
contact GET /contact(.:format) static_pages#contact
help GET /help(.:format) static_pages#help
legal GET /legal(.:format) static_pages#legal
change:
resources :users do
member do
post 'edit_profile'
end
end
use edit_profile_user_path(#user) instead.
In the Devise login-page, the value of resource_name is just a string "user"... you want to be pointing at an actual user's page, for that you need an actual user instance.... which for Devise's login page is what is stored in resource... but after you're logged in, it's stored in current_user.
However, your code seems to indicate that you're putting user into #user - so that's what I'd use.
I've got an embedded resource inside of a singular resource (/profile/workout) and am having some problems with the form_for helper.
I've defined the following helper, since profile is just based off the current_user (just redirects to the right url):
def workout_path(*args)
profile_workout_path(*args)
end
I've got the following model:
class Workout
include Mongoid::Document
include Mongoid::Timestamps
field :name, type: String
embedded_in :user
embeds_many :movements
accepts_nested_attributes_for :movements
end
controller:
def new
#workout = current_user.workouts.build
#workout.movements.build
end
routes:
ComposerDelete::Application.routes.draw do
authenticated :user do
root :to => 'home#index'
end
root :to => "home#index"
devise_for :users
resources :users do
end
resource :profile do
resources :workouts
end
end
and form
= form_for #workout do |f|
%fieldset
= f.label :name
= f.text_field :name
= f.fields_for :movements do |builder|
= render "movement_fields", f: builder
= link_to_add_fields "Add Movement", f, :movements
= f.submit "Create"
When I visit the url: http://localhost:3500/profile/workouts/50b99b70f0f800cd53000002/edit, the form has the following header:
<form accept-charset="UTF-8" action="/profile/workouts/50b99b70f0f800cd53000002" class="edit_workout" id="edit_workout_50b99b70f0f800cd53000002" method="post">
It gets the right id (edit_<model>_<id>), but the wrong method (post, should be put), also, the submit button says Create instead of Update. The form works correctly, and updates the workout.
rake routes:
root / home#index
root / home#index
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
profile_workouts GET /profile/workouts(.:format) workouts#index
POST /profile/workouts(.:format) workouts#create
new_profile_workout GET /profile/workouts/new(.:format) workouts#new
edit_profile_workout GET /profile/workouts/:id/edit(.:format) workouts#edit
profile_workout GET /profile/workouts/:id(.:format) workouts#show
PUT /profile/workouts/:id(.:format) workouts#update
DELETE /profile/workouts/:id(.:format) workouts#destroy
profile POST /profile(.:format) profiles#create
new_profile GET /profile/new(.:format) profiles#new
edit_profile GET /profile/edit(.:format) profiles#edit
GET /profile(.:format) profiles#show
PUT /profile(.:format) profiles#update
DELETE /profile(.:format) profiles#destroy
The method will always be POST, not PUT - your browser does not support PUT natively, so Rails hacks around this by using a hidden form field inside the form with _method=PUT. See here for some documentation on this.
also, your own code says = f.submit "Create" so it's no wonder the button says 'Create'.