Couldn't find User without an ID when calling method - ruby-on-rails

I got a modal, with a form inside it. However I get the classic error when I try to submit:
Couldn't find User without an ID
My form looks like this:
<%= form_for add_email_users_path, url: { action: 'add_email', controller: 'users' } do |f| %>
<%= f.email_field :email, placeholder: 'Your email address', class: 'input-lg form-control' %>
<%= f.button 'Continue', class: 'btn btn-success', 'data-disable-with' => "Saving <i class='fa fa-spinner fa-spin'></i>".html_safe %>
<% end %>
routes:
resources :users, except: [:destroy] do
post 'add_email', on: :collection
end
User_controller:
def add_email
#user = User.find(params[:id])
if #user.update_attributes(setup_params)
redirect_to campaigns_path, notice: 'Thank you for adding your email!'
else
redirect_to :back, alert: 'Unable to save your email'
end
end

Try this:
<%= form_for add_email_users_path(#user) do |f| %>
<%= f.email_field :email, placeholder: 'Your email address', class: 'input-lg form-control' %>
<%= f.button 'Continue', class: 'btn btn-success', 'data-disable-with' => "Saving <i class='fa fa-spinner fa-spin'></i>".html_safe %>
<% end %>
and your route:
resources :users, except: [:destroy] do
post 'add_email', on: :member
end

You have the wrong path method in your form_for, it should be:
add_email_user_path(#user)
And your route should be for member not collection:
post 'add_email', on: :member
Here is what your stuff should look like:
form.html.erb
<%= form_for add_email_user_path(#user) do |f| %>
<%= f.email_field :email, placeholder: 'Your email address', class: 'input-lg form-control' %>
<%= f.button 'Continue', class: 'btn btn-success', 'data-disable-with' => "Saving <i class='fa fa-spinner fa-spin'></i>".html_safe %>
<% end %>
routes.rb
resources :users, except: [:destroy] do
post :add_email, on: :member
end
Take special note of the change to the form_for call.

It can't be a collection method as it is looking for specific id define it as a member method
resources :users, except: [:destroy] do
member do
post :add_email
end
end
In form
<%= form_for add_email_user_path(#user), method: :post do |f| %>
You can refer to this docs to understand member and collection methods

Related

undefined method `wikis_path'

I am having issues getting my create method to function correctly.
Here is my new.html.erb file
<div class="col-md-8">
<%= form_for #wiki do |f| %>
<%= f.label :title, class: 'form-control' %>
<%= f.text_field :title, class: 'form-control', placeholder: "Enter wiki title" %><br><br>
<%= f.label :body, class: 'form-control'%>
<%= f.text_area :body, class: 'form-control', placeholder: "Enter wiki body" %><br><br>
<%= f.check_box :private %> Private Topic<br><br>
<%= f.submit "Save", class: 'btn btn-success' %>
<% end %>
</div>
Controller
def new
#wiki = Wiki.new
end
def create
#wiki = Wiki.create(params[:wiki])
if #wiki.save
flash[:notice] = "Wiki has been saved"
redirect_to wiki_index_path
end
end
private
def wiki_params
params.require(:wiki).permit(:title, :body, :private)
end
routes.rb
Rails.application.routes.draw do
devise_for :users
resources :wiki
post 'wiki/new'
post 'wiki/create'
resources :users
root 'welcome#index'
end
If I use :wiki in my form_for on new.html.erb I can get passed the error but when clicking on my save button on the actual new page, nothing happens at all (since I'm not saving the information to the correct variable). However, as soon as I use the #wiki variable, I get the error
"undefined method `wikis_path' for #<#<Class:0x007f8f794e5d58>:0x007f8f7bb2ef50>"
Any help is appreciated!
You can get rid of redundant unrestful wiki routes. resources :wikis will be enough:
Rails.application.routes.draw do
devise_for :users
resources :wikis
resources :users
root 'welcome#index'
end
And something tells me that all will be fine after that change.

Routing error - No route matches [POST]

Have read many questions / answers on this issue, yet do not seem to find my fix.
Here is the issue: I am following the getting started for Rails to create a simple register of annotations. My forms work - can add new & update annotations. Yet when I add links to the index, I get a routing error:
This: <%= button_to "Details", annotation_path(annotation), :class => "btn btn-primary btn-xs"%> results in: No route matches [POST] "/annotations/5"
This: <%= button_to "Add Annotation", new_annotation_path, :class => "btn btn-primary btn-xs"%> to No route matches [POST] "/annotations/new"
Thanks for help
Routes.db:
Rails.application.routes.draw do
root 'dashboard#index'
devise_for :users
resources :users, :annotations
Controller:
class AnnotationsController < ApplicationController
def index
#annotations = Annotation.all
end
def show
#annotation = Annotation.find(params[:id])
end
def new
#annotation = Annotation.new
end
def edit
#annotation = Annotation.find(params[:id])
end
def create
#annotation = Annotation.new(annotation_params)
#annotation.save
redirect_to #annotation
end
def update
#annotation = Annotation.find(params[:id])
if #annotation.update(annotation_params)
redirect_to #annotation
else
render 'edit'
end
end
def destroy
#annotation = Annotation.find(params[:id])
#annotation.destroy
redirect_to annotations_path
end
private
def annotation_params
params.require(:annotation).permit(:name, :description)
end
end
And the form (= partial)
<%= simple_form_for #annotation, url: annotations_path, html: { class: 'form-horizontal' },
wrapper: :horizontal_form,
wrapper_mappings: {
check_boxes: :horizontal_radio_and_checkboxes,
radio_buttons: :horizontal_radio_and_checkboxes,
file: :horizontal_file_input,
boolean: :horizontal_boolean
} do |f| %>
<%= f.error_notification %>
<%= f.input :name, placeholder: 'Enter name' %>
<%= f.input :description, placeholder: 'Description' %>
<%= f.input :file, as: :file %>
<%= f.input :active, as: :boolean %>
<%= f.input :choice, as: :check_boxes,
collection: [
'Option one ...',
'Option two ...'] %>
<%= f.input :documenttype, as: :radio_buttons,
collection: ['Type1', 'Type2'] %>
<%= f.button :submit %>
<% end %>
Note on the form: to no avail, I tried using <%= simple_form_for :annotation, url: annotations_path,
The issue is because the button_to helper actually generates a form at code level and thus is POSTing said form, however the route for a new resource must be a GET.
The button_to tag really should not be used for GET requests so I would use a link_to with CSS classes instead (you already have the necessary classes), but you can do it using the below if you wanted:
<%= button_to "Details", annotation_path(annotation), class: "btn btn-primary btn-xs", method: :get%>
The better approach however is:
<%= link_to "Details", annotation_path(annotation), class: "btn btn-primary btn-xs" %>
Read doc here button_to
The method is by default :post change it using :method param
<%= button_to "Details", annotation_path(annotation), :class => "btn btn-primary btn-xs", method: :get%>
<%= button_to "Add Annotation", new_annotation_path, :class => "btn btn-primary btn-xs", method: :get%>

form_for issue GET request instead of patch

I have edit form for company as bellow in edit.html.erb
<%= form_for([:dashboard , #company] ) do |f| %>
<%= f.text_field :name , :class => "form-control" %>
<%= f.submit "Save" , :class => "btn btn-primary"%>
<% end %>
and my companies_controller.rb
def edit
#company = Company.find(params[:id])
end
def update
# Update code
end
and my routes.rb
namespace :dashboard do
resources :companies , only: [ :edit , :update ]
end
The problem is when submit the form get the bellow error
No route matches [GET] "/dashboard/companies/3"
form_for accepts a post method by default.Here the edit action is get method,so your form_for should look like this
<%= form_for([:dashboard , #company],:html => {:method => :get }) do |f| %>
<%= f.text_field :name , :class => "form-control" %>
<%= f.submit "Save" , :class => "btn btn-primary"%>
<% end %>
OR
You can do like this too
<%= form_for([:dashboard , #company] :url =>edit_dashboard_company_path(#company)) do |f| %>
<%= f.text_field :name , :class => "form-control" %>
<%= f.submit "Save" , :class => "btn btn-primary"%>
<% end %>

No route matches [POST] "/organizations/new"

In my rails app I got quite a few resources and have created a few forms already - but for some reason I don't seem to get one specific form for a new object to work. I am not sure if it is because I am using a three-way has_many :through relationship or because I am just overlooking something else
Here's how my routes looks like
resources :users, shallow: true do
resources :organizations, :notifications
end
resources :organizations, shallow: true do
resources :plans, :users, :notifications
end
My organizations_controller looks like this:
def index
#user = current_user
#organizations = #user.organizations.to_a
end
def show
#user = current_user
#organization = Organization.find(params[:id])
end
def new
#organization = Organization.new
end
def create
#user = current_user
#organization = Organization.new(organization_params)
#organization.save
redirect_to #organization
end
On my organizations index page I link to this:
<%= button_to 'New Organization', new_organization_path, :class => 'btn btn-primary' %>
which should lead to my new.html.erb:
<%= form_for (#organization) do |f| %>
<%= render 'layouts/messages' %>
<div class="form-group">
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :website %>
<%= f.text_area :website, class: 'form-control' %>
</div>
<%= f.button :class => 'btn btn-primary' %>
<% end %>
Every time I click on "new Organization" I get following error:
No route matches [POST] "/organizations/new"
Which is correct - I do not have a new_organizations_path that accepts POST requests. I know I can manually change the method of the form to GET but shouldn't it work the way I did it? I have another form that follows the same principle just for a different resource and it works perfectly.
Thanks for your help in advance!
button_to would always send a POST request unless something else is specified.
On the other form, you must be using link_to and not button_to which is why its working there.
You can change the button_to in two ways, pick the one that suits you:
Option 1: Use link_to
<%= link_to 'New Organization', new_organization_path, :class => 'btn btn-primary' %>
Option 2: Use button_to with method: :get
<%= button_to 'New Organization', new_organization_path, method: :get, :class => 'btn btn-primary' %>

Rails mailboxer gem cannot send message

I am using Mailboxer gem for the messaging function, but as I am very new I am not very sure how to use it. Basically I created the following message controller:
class MessagesController < ApplicationController
before_action :set_message, only: [:new, :create]
def new
#message = Message.new
end
def create
current_user.send_message(#recipient, message_params(:body, :subject))
redirect_to conversations_path
end
private
def set_message
#recipient = User.find(params[:recipient_id])
end
def message_params
params.require(:message).permit(:body, :subject)
end
end
Then my view:
<h1>New Message</h1>
<%= simple_form_for(#message, html: {class: "form-horizontal"}) do |f| %>
<%= f.error_notification %>
<%= f.input :subject %>
<%= f.input :body, as: :text, input_html: { rows: "3"} %>
<div class="form-actions">
<%= f.button :submit, class: "btn btn-primary" %>
</div>
<% end %>
But I can't send message...
(BTW I can send message is the console, and also replace part of the message controller with "current_user.send_message(#recipient, "test", "test")", but definitely not what I want)
Use form_tag instead of form_for
Instead of using form_for, try using form_tag, as this has worked for me:
<%= form_tag("/messages/send_message", method: "post", url: send_message_path) do %>
<%= hidden_field_tag :user_id, "#{#user.id}" %>
<%= text_field_tag :subject, nil, :class => 'form-control', :placeholder => "Subject" %>
<%= text_area_tag :message, nil, :class => 'form-control', :placeholder => "Message" %>
<%= submit_tag "Submit", :class => "btn btn-primary" %>
<% end %>
This would have an action you messages controller like this:
def send_message
#user = User.find(params[:user_id])
#message = params[:message]
#subject = params[:subject]
current_user.send_message(#user, "#{#message}", "#{#subject}")
redirect_to root_path
end
And something like this in you routes file:
post '/messages/send_message', :to => "messages#send_message", :as => "send_message"
Really hope this helps!

Resources