When I attempt to render this view:
Reply:
<%= form_for :message, url: [:reply, conversation] do |f| %>
<%= f.text_area :body %>
<%= f.submit "Send Message", class: 'btn btn-primary' %>
<%= submit_tag 'Clear Reply Box', type: :reset, class: 'btn btn-danger' %>
<% end %>
I get the error: undefined method 'reply_mailboxer_conversation_path'
Routes:
resources :messages do
member do
post :new
end
end
resources :conversations do
member do
post :reply
post :trash
post :untrash
end
collection do
get :trashbin
post :empty_trash
end
end
rake routes output:
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
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 / profiles#index
message POST /messages/:id(.:format) messages#new
messages GET /messages(.:format) messages#index
POST /messages(.:format) messages#create
new_message GET /messages/new(.:format) messages#new
edit_message GET /messages/:id/edit(.:format) messages#edit
GET /messages/:id(.:format) messages#show
PATCH /messages/:id(.:format) messages#update
PUT /messages/:id(.:format) messages#update
DELETE /messages/:id(.:format) messages#destroy
reply_conversation POST /conversations/:id/reply(.:format) conversations#reply
trash_conversation POST /conversations/:id/trash(.:format) conversations#trash
untrash_conversation POST /conversations/:id/untrash(.:format) conversations#untrash
trashbin_conversations GET /conversations/trashbin(.:format) conversations#trashbin
empty_trash_conversations POST /conversations/empty_trash(.:format) conversations#empty_trash
conversations GET /conversations(.:format) conversations#index
POST /conversations(.:format) conversations#create
new_conversation GET /conversations/new(.:format) conversations#new
edit_conversation GET /conversations/:id/edit(.:format) conversations#edit
conversation GET /conversations/:id(.:format) conversations#show
PATCH /conversations/:id(.:format) conversations#update
PUT /conversations/:id(.:format) conversations#update
DELETE /conversations/:id(.:format) conversations#destroy
Really not sure what I'm doing wrong. If I've left out any important code, please just let me know.
https://github.com/portOdin/gfi2/tree/june6/app/views
The error you're receiving is because of how you're defining your form_for block:
<%= form_for :message, url: [:reply, conversation] do |f| %>
From the docs:
Resource-oriented style
In the examples just shown, although not indicated explicitly, we
still need to use the :url option in order to specify where the form
is going to be sent. However, further simplification is possible if
the record passed to form_for is a resource, i.e. it corresponds to a
set of RESTful routes, e.g. defined using the resources method in
config/routes.rb. In this case Rails will simply infer the appropriate
URL from the record itself. For example,
<%= form_for #post do |f| %>
...
<% end %>
is then equivalent to something like:
<%= form_for #post, as: :post, url: post_path(#post), method: :patch, html: { class: "edit_post", id: "edit_post_45" } do |f| %>
...
<% end %>
--
Nested
When you use an array for the resource part of form_for, you're basically telling rails that conversation will inherit from reply.
We use it like this:
<%= form_for [:admin, #object] do |f| %>
This basically treats the url attribute like this:
url: reply_conversation_path
I don't know where it got mailboxer from, but either way, the problem will be caused by the declaration of [:reply, conversation].
--
Fix
There are two ways to fix this.
The first is to use the url: attribute inside the form_for, like this:
<%= form_for [:reply, #conversation], url: reply_conversation_path(conversation) do |f| %>
The second is to use the correct formatting:
<%= form_for #reply, url: reply_conversation_path(#conversation) do |f| %>
...
<% end %>
There are two things that you have to keep in mind whenever you make a form
a. You need to initialise your resource in your controller, in your case reply. I'm assuming you are in show action of conversations controller so you can initialise it like this:
#reply = Message.new # assuming you dont have a reply model and you are using message model as reply
b. The path where you are creating your resource. If you look at your rake routes
reply_conversation POST /conversations/:id/reply(.:format) conversations#reply. You can clearly see that you need to have a conversation to make a reply in that conversation so again you'll have to find that conversation in your show action of conversations controller like this:
#conversation = Conversation.find(params[:id])
Now to make a form is relatively simple
<% form_for #reply, url: reply_conversation_path(#conversation.id) do |f| %>
<%= #your fields %>
<% end %>
Related
Happy Thursday everyone, I had a quick question on routes and redirecting. I am working on a rails assignment that asks that I redirect the router to his/her profile after signing in. How would I go about doing that? An after_sign_in method? Here is my routes:
Rails.application.routes.draw do
get 'users/show'
get 'users_controller/show'
devise_for :users
resources :users
get 'welcome/index'
root :to => 'welcome#index'
end
Users Controller:
class UsersController < ApplicationController
def show
#user = User.find(params[:id])
end
private
def user_params
params.require(:user).permit(:name, :email)
end
end
devise/sessions (Login Page)
<h2>Sign in</h2>
<div class="row">
<div class="col-md-8">
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div class="form-group">
<%= f.label :email %>
<%= f.email_field :email, autofocus: true, class: 'form-control', placeholder: "Enter email" %>
</div>
<div class="form-group">
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control', placeholder: "Enter password" %>
</div>
<div class="form-group">
<% if devise_mapping.rememberable? %>
<%= f.label :remember_me, class: 'checkbox' do %>
<%= f.check_box :remember_me %> Remember me
<% end %>
<% end %>
<%= f.submit "Sign in", class: 'btn btn-success' %>
</div>
<div class="form-group">
<%= render "devise/shared/links" %>
</div>
<% end %>
</div>
</div>
Thanks for your help! Also could anyone answer why my rake routes has two users#show? I know only one functions (the one with the user_id) so I don't know how two were created.
Rake Routes Output:
rake routes
Prefix Verb URI Pattern Controller#Action
users_show GET /users/show(.:format) users#show
users_controller_show GET /users_controller/show(.:format) users_controller#show
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
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
welcome_index GET /welcome/index(.:format) welcome#index
root GET /
welcome#index
Define after_sign_in_path_for in ApplicationController. Read this: https://github.com/plataformatec/devise/wiki/How-To%3A-Redirect-to-a-specific-page-on-successful-sign-in-and-sign-out
By default, Devise will redirect the user to the root_path after signing in. You can simply change the root setting in config/routes.rb to the desired path, or add a user_root_path, e.g.
get '/welcome' => "welcome#index", as: :user_root
as describe in the Devise wiki.
As to the two routes, note that your routes.rb includes these two statements:
get 'users/show'
resources :users
resources automatically adds a route at GET /users/:id mapping to UsersController#show, which is what you want. The other route should be removed, along with get 'users_controller/show'. More info on this can be found in the Rails Routing Guide.
In the applicaion controller
def after_sign_in_path_for(user)
the link that you want
end
in your example
def after_sign_in_path_for(user)
user_path(current_user.id)
end
I have two forms for new and edit that I want to extract to a partial, but, to my begginer knowledge in Rails, they need different paths in order to work.
This is my edit form:
<%= simple_form_for [#user, #wiki], url: user_wiki_path do |f| %>
<%= f.input :title %>
<%= f.input :body %>
<%= f.submit class: "btn btn-success" %>
<% end %>
This is my new form:
<%= simple_form_for [#user, #wiki], url: user_wikis_path, method: :post do |f| %>
<%= f.input :title %>
<%= f.input :body %>
<%= f.submit class: "btn btn-success" %>
<% end %>
Can I, and if so, how, combine them into one partial _form.html.erb conditionally specifing the paths?
When I try joining them now I get the error below when trying to edit it:
No route matches [PATCH] "/users/32/wikis"
These are my routes:
Prefix Verb URI Pattern Controller#Action
users_index GET /users/index(.:format) users#index
users_show GET /users/show(.:format) users#show
root GET / pages#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
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_wikis POST /users/:user_id/wikis(.:format) wikis#create
new_user_wiki GET /users/:user_id/wikis/new(.:format) wikis#new
edit_user_wiki GET /users/:user_id/wikis/:id/edit(.:format) wikis#edit
user_wiki PATCH /users/:user_id/wikis/:id(.:format) wikis#update
PUT /users/:user_id/wikis/:id(.:format) wikis#update
DELETE /users/:user_id/wikis/:id(.:format) wikis#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
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
wikis GET /wikis(.:format) wikis#index
wiki GET /wikis/:id(.:format) wikis#show
charges POST /charges(.:format) charges#create
new_charge GET /charges/new(.:format) charges#new
charge PATCH /charges/:id(.:format) charges#update
PUT /charges/:id(.:format) charges#update
You can post local variables into the partial. Something like the following would work:
new.html.erb
<%= render partial: '_form', locals: {url: user_wikis_path, method: :post} %>
edit.html.erb
<%= render partial: '_form', locals: {url: user_wiki_path(#user, #wiki), method: :post} %>
_form.html.erb
<%= simple_form_for [#user, #wiki], url: url, method: method do |f| %>
<%= f.input :title %>
<%= f.input :body %>
<%= f.submit class: "btn btn-success" %>
<% end %>
Or you could set #url and #method as instance variables and access them that way.
Controller
def new
#method = :get
#url = user_wikis_path
...
end
def edit
#method = :post
#url = user_wiki_path(#user, #wiki)
...
end
_form.html.erb
<%= simple_form_for [#user, #wiki], url: url, method: method do |f| %>
...
Or you could have a conditional in the form that accesses the current action, if you use action_name in the view it'll return the name of the current action.
# _form.html.erb
<%= simple_form_for #wiki do |f| %>
<%= f.input :title %>
<%= f.input :body %>
<%= f.submit class: "btn btn-success" %>
<% end %>
and on your wikis#edit and wikis#new, add
...
#user = User.find params[:user_id]
...
I'm trying to add comment functionality of my Reddit clone. This is the comments controller that creates a comments and adds it to a post.
class CommentsController < ApplicationController
def new
#topic = Topic.find(params[:topic_id])
#post = Post.find(params[:id])
#comment = Comment.new
#authorize #comment # from include Pundit in the application controller, authorize is an inherited method
end
def create
#topic = Topic.find(params[:topic_id])
#post = Post.find(params[:id])
#comment = current_user.comments.build(comment_params)
end
private
def comment_params
params.require(:comment).permit(:text)
end
end
I'm trying to add a comments field for every post page by using a form partial that looks like this:
<%= form_for [topic, post] do |f| %>
<%= form_group_tag(comment[:text]) do %>
<%= f.label :text %>
<%= f.text_area :text, rows: 10, class: 'form-control', placeholder: "Enter your comment" %>
<% end %>
<div class = "form-group">
<%= f.submit "Save", class: 'btn btn-success' %>
</div>
<% end %>
This form partial should appear at the post.show.html.erb so I put it there
<h1><%= markdown #post.title %></h1>
<div class="row"> <!-- what others are there besides row? -->
<div class="col-md-8">
<p><%= markdown #post.body %></p>
</div>
<div class="col-md-4">
<% if policy(#post).edit? %>
<%= link_to "Edit", edit_topic_post_path(#topic, #post), class: 'btn btn-success' %>
<% end %>
</div>
<div class="col-md-8">
<%= render partial: 'comments/form', locals: { topic: #topic, post: #post, text: #post.comments.new } %>
</div>
</div>
but I'm getting a NameError for my 'comment' on the form_group_tag line. Most of what I defined here comes from my code for adding new posts, which seemed to work. Is there something missing here?
I fixed my name error by adding comments to the form_for line, but I'm getting NoMethodError for my topic,post,comment path, so I thought it'd be helpful to add what rake routes is pulling up.
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 PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
topic_posts POST /topics/:topic_id/posts(.:format) posts#create
new_topic_post GET /topics/:topic_id/posts/new(.:format) posts#new
edit_topic_post GET /topics/:topic_id/posts/:id/edit(.:format) posts#edit
topic_post GET /topics/:topic_id/posts/:id(.:format) posts#show
PATCH /topics/:topic_id/posts/:id(.:format) posts#update
PUT /topics/:topic_id/posts/:id(.:format) posts#update
DELETE /topics/:topic_id/posts/:id(.:format) posts#destroy
topics GET /topics(.:format) topics#index
POST /topics(.:format) topics#create
new_topic GET /topics/new(.:format) topics#new
edit_topic GET /topics/:id/edit(.:format) topics#edit
topic GET /topics/:id(.:format) topics#show
PATCH /topics/:id(.:format) topics#update
PUT /topics/:id(.:format) topics#update
DELETE /topics/:id(.:format) topics#destroy
post_comments POST /posts/:post_id/comments(.:format) comments#create
posts GET /posts(.:format) posts#index
POST /posts(.:format) posts#create
new_post GET /posts/new(.:format) posts#new
edit_post GET /posts/:id/edit(.:format) posts#edit
post GET /posts/:id(.:format) posts#show
PATCH /posts/:id(.:format) posts#update
PUT /posts/:id(.:format) posts#update
DELETE /posts/:id(.:format) posts#destroy
about GET /about(.:format) welcome#about
root GET / welcome#index
BTW: how does this routes.rb file look?
Rails.application.routes.draw do
devise_for :users
resources :users, only: [:update]
resources :topics do
resources :posts, except: [:index]
end
resources :posts do
resources :comments, only: [:create]
end
end
Try:
<%= render partial: 'comments/form', locals: { topic: #topic, post: #post, comment: #post.comments.new } %>
...
<%= form_for [post, comment] do |f| %>
<%= f.label :text %>
<%= f.text_area :text, rows: 10, class: 'form-control', placeholder: "Enter your comment" %>
<%= f.submit "Save", class: 'btn btn-success' %>
<% end %>
...
If it does not help, try to temporary comment form_group_tag and send error here
It seems like you're sending the comment down to the partial as text.
... locals: { topic: #topic, post: #post, text: #post.comments.new } %>
^^^^
And by the way you're not saving the comment in the create action.
I am dealing with a nested resource "farm" in Rails, and my form for making new farm looks like this:
<%= form_for([#user, #farm], :url=> new_user_farm_path(#user)) do |f| %>
<% if #farm.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#farm.errors.count, "error") %> prohibited this farm from being saved:</h2>
<ul>
<% #farm.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :contact %><br />
<%= f.text_field :contact %>
</div>
<div class="field">
<%= f.label :adress %><br />
<%= f.text_field :adress %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
My corresponding "new" function in the farms controller is:
def new
#farm = Farm.new
#user = User.find(current_user)
respond_to do |format|
format.html # new.html.erb
format.json { render json: #farm }
end
end
It renders the form just fine, but after I click submit, and it actually tries to create new Farm, I get this error:
No route matches [POST] "/users/2/farm/new"
In my rake routes, I clearly have thie route showing:
user_farm POST /users/:user_id/farm(.:format) {:action=
create", :controller=>"farms"}
I am only guessing that the problem is in my create function:
def create
#farm = Farm.new(params[:farm])
#user = User.find(current_user)
respond_to do |format|
if #farm.save
format.html { redirect_to user_farm(#user, #farm), notice: 'Farm was successfully created.' }
format.json { render json: #farm, status: :created, location: #farm }
else
format.html { render action: "new" }
format.json { render json: #farm.errors, status: :unprocessable_entity }
end
end
end
My routes.rb file:
resources :users do
resource :farm
end
devise_for :users, :path => 'accounts'
I am accessing my new farm form via this link:
<%= link_to "New Farm", new_user_farm_path(current_user) %>
My entire rake routes:
user_farm POST /users/:user_id/farm(.:format) {:action=>"
create", :controller=>"farms"}
new_user_farm GET /users/:user_id/farm/new(.:format) {:action=>"
new", :controller=>"farms"}
edit_user_farm GET /users/:user_id/farm/edit(.:format) {:action=>"
edit", :controller=>"farms"}
GET /users/:user_id/farm(.:format) {:action=>"
show", :controller=>"farms"}
PUT /users/:user_id/farm(.:format) {:action=>"
update", :controller=>"farms"}
DELETE /users/:user_id/farm(.:format) {:action=>"
destroy", :controller=>"farms"}
users GET /users(.:format) {:action=>"
index", :controller=>"users"}
POST /users(.:format) {:action=>"
create", :controller=>"users"}
new_user GET /users/new(.:format) {:action=>"
new", :controller=>"users"}
edit_user GET /users/:id/edit(.:format) {:action=>"
edit", :controller=>"users"}
user GET /users/:id(.:format) {:action=>"
show", :controller=>"users"}
PUT /users/:id(.:format) {:action=>"
update", :controller=>"users"}
DELETE /users/:id(.:format) {:action=>"
destroy", :controller=>"users"}
new_user_session GET /accounts/sign_in(.:format) {:action=>"
new", :controller=>"devise/sessions"}
user_session POST /accounts/sign_in(.:format) {:action=>"
create", :controller=>"devise/sessions"}
destroy_user_session GET /accounts/sign_out(.:format) {:action=>"
destroy", :controller=>"devise/sessions"}
user_password POST /accounts/password(.:format) {:action=>"
create", :controller=>"devise/passwords"}
new_user_password GET /accounts/password/new(.:format) {:action=>"
new", :controller=>"devise/passwords"}
edit_user_password GET /accounts/password/edit(.:format) {:action=>"
edit", :controller=>"devise/passwords"}
PUT /accounts/password(.:format) {:action=>"
update", :controller=>"devise/passwords"}
cancel_user_registration GET /accounts/cancel(.:format) {:action=>"
cancel", :controller=>"devise/registrations"}
user_registration POST /accounts(.:format) {:action=>"
create", :controller=>"devise/registrations"}
new_user_registration GET /accounts/sign_up(.:format) {:action=>"
new", :controller=>"devise/registrations"}
edit_user_registration GET /accounts/edit(.:format) {:action=>"
edit", :controller=>"devise/registrations"}
PUT /accounts(.:format) {:action=>"
update", :controller=>"devise/registrations"}
DELETE /accounts(.:format) {:action=>"
destroy", :controller=>"devise/registrations"}
user_confirmation POST /accounts/confirmation(.:format) {:action=>"
create", :controller=>"devise/confirmations"}
new_user_confirmation GET /accounts/confirmation/new(.:format) {:action=>"
new", :controller=>"devise/confirmations"}
GET /accounts/confirmation(.:format) {:action=>"
show", :controller=>"devise/confirmations"}
user_unlock POST /accounts/unlock(.:format) {:action=>"
create", :controller=>"devise/unlocks"}
new_user_unlock GET /accounts/unlock/new(.:format) {:action=>"
new", :controller=>"devise/unlocks"}
GET /accounts/unlock(.:format) {:action=>"
show", :controller=>"devise/unlocks"}
home_index GET /home/index(.:format) {:controlle
r=>"home", :action=>"index"}
root / {:controlle
r=>"home", :action=>"index"}
The problem is that your form is attempting to make a POST request to a url that only exists for GET requests. So it's telling you that
[POST] "/users/2/farm/new"
doesn't exist -- which it doesn't. And your rake routes output confirms this -- the cloesst thing is
new_user_farm GET /users/:user_id/farm/new(.:format)
which is a GET request.
Forms default to using POST for new record creation, so you need to supply a url that can be POSTed to. Or you can let Rails figure it out from the state of your objects. So either
<%= form_for([#user, #farm], :url=> user_farm_path(#user)) do |f| %>
OR
<%= form_for([#user, #farm]) do |f| %>
should work. In the former case we're using a named route that matches a POST route from your rake routes output. In the latter case we're letting rails figure it out based on the state of your #farm object. That is, if #farm is a new_record? it'll submit a POST request to /users/:user_id/farm, or if #farm is persisted? then it'll submit a PUT request to /users/:user_id/farm. (Same path, just different request type.)
Some issues:
--
Params
When you create a new ActiveRecord object in Rails, you'll want to use strong params:
#app/controllers/farms_controller.rb
Class FarmsController < ApplicationController
def new
#farm = Farm.new
end
def create
#farm = Farm.new(farm_params)
end
private
def farm_params
params.require(:farm).permit(:params, :for, :farm)
end
end
--
Routes
You're using nested routing, which can be tricky if you're not used to it.
If you haven't already, you should do this with your routes:
#config/routes.rb
resources :users do
resources :farm #-> /users/3/farm/new
end
This will give you the ability to reach that route either from your controller or views.
If you give me some more info (Routes file), I'll be able to help further!
--
POST
Having looked over the issue again, it seems I made an oversight before!!!
As pointed out by pdbobb, the error certainly says you're trying to reach /new with a POST verb. This is not correct, as according to the Rails resourceful routing conventions, you need to
You'll be able to use pdobb's answer, but more importantly, we need to establish why your form is trying to submit to the new post.
The problem is likely with your nested resource
Whenever I try to log in and sign up, I am hit with this error:
undefined method `username' for nil:NilClass
on these two lines:
<strong><%= #user.username %></strong> <br>
<strong><%= #user.name %></strong>
Here is the full error from the server's output:
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."username" = 'sign_in' LIMIT 1
Rendered users/show.html.erb within layouts/application (2.1ms)
Completed 500 Internal Server Error in 7ms
ActionView::Template::Error (undefined method `username' for nil:NilClass):
1: <strong><%= #user.username %></strong> <br>
2: <strong><%= #user.name %></strong>
3: <%= debug #user %>
4:
app/views/users/show.html.erb:1:in `_app_views_users_show_html_erb__1133891108745893964_2164088020'
Here are my routes:
Stynyl::Application.routes.draw do
resources :things
resources :users, only: [:show]
devise_for :users
get '/about', to: 'pages#about'
root 'things#index'
end
Here is my user show view
<strong><%= #user.username %></strong> <br>
<strong><%= #user.name %></strong>
<div id="things" class="transitions-enabled">
<% #user.things.each do |thing| %>
<div class='panel panel default'>
<div class="box">
<%= link_to image_tag(thing.image.url(:medium)), thing %>
<div class='panel-body'>
<strong><p><%= thing.title %></p></strong>
<p><%= thing.description %></p>
By <%= link_to thing.user.username, thing.user %>
<% if thing.user == current_user %>
<%= link_to edit_thing_path(thing) do %>
<span class='glyphicon glyphicon-edit'></span> Edit
<% end %>
<%= link_to thing_path(thing), method: :delete, data: { confirm: 'Are you sure?' } do %>
<span class='glyphicon glyphicon-trash'></span> Delete
<% end %>
</div>
<% end %>
</div>
</div>
<% end %>
</div>
Here is my UsersController file:
class UsersController < ApplicationController
def show
#user = User.find_by_username(params[:id])
end
end
Output of rake routes:
Prefix Verb URI Pattern Controller#Action
things GET /things(.:format) things#index
POST /things(.:format) things#create
new_thing GET /things/new(.:format) things#new
edit_thing GET /things/:id/edit(.:format) things#edit
thing GET /things/:id(.:format) things#show
PATCH /things/:id(.:format) things#update
PUT /things/:id(.:format) things#update
DELETE /things/:id(.:format) things#destroy
users POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
user GET /users/:id(.:format) users#show
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
about GET /about(.:format) pages#about
root GET / things#index
Edits
I also noticed that when I delete all of the code from the User show view, I can get to the signup and login pages, but they are blank. Can we safely guarantee that the problem is in the view? I'm so perplexed at how something in the show view can affect the ability to sign in and sign up!
I have also observed that when I add content to the users show view, it appears on the sign up and login pages. What on earth is going on?
The reason is because of a conflict in your routes. When matching a request to a route, Rails will go through your routes sequentially. But your order shows:
user GET /users/:id(.:format) users#show
new_user_session GET /users/sign_in(.:format) devise/sessions#new
And so Rails is passing sign_in as the :id parameter to your user show method, instead of being caught by devise's new_user_session_path. Changing the order will fix the problem.
TL:DR; devise_for :users should be declared before resources :users.