undefined method `wikis_path' - ruby-on-rails

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.

Related

Edit simple_form_for with namespace

I'm trying to create a form with Simple Form to edit users profile from admin interface.
Here are my routes :
namespace :admin do
resources :users
root 'admin#index'
end
Admin::UsersController :
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
if #user.update(user_params)
redirect_to admin_user_path(#user.id)
else
render :edit
end
end
And my view :
<div class='container mt-4'
<%= simple_form_for [:admin, #user] do |f| %>
<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
<%= f.input :first_name, label: 'Prénom' %>
<%= f.input :last_name, label: 'Nom' %>
<%= f.input :description %>
<%= f.input :email %>
<%= f.button :submit, 'Enregistrer les modifications', class: 'btn btn-primary rounded' %>
<% end %>
</div>
But my form doesn't work, nothing happen when I click the button... What did I miss ?
I think that the problem is in the route.
namespace :admin do
resources :users
root 'admin#index'
get 'admin#update'
end

Form inside a loop how to do it the Rails way?

Hi I have a working "blog module" on my page.
From the start. My routes looks like this:
root 'static_pages#home'
resources :announcements, only: [:new,:create,:update,:edit,:destroy,:show] do
resources :comments, only: [:create, :destroy]
end
My controller actions looks like this:
static_pages_controllers.rb
def home
#announcements = Announcement.page(params[:page]).order('id DESC')
end
announcements_controller.rb
def new
#announcement = Announcement.new
end
def create
#announcement = Announcement.new(announcement_params)
if #announcement.save
flash[:success] = "Post został pomyślnie dodany"
redirect_to root_path
else
render 'new'
end
end
comments_controller.rb
def create
#announcement = Announcement.find(params[:announcement_id])
#comment = #announcement.comments.new(comments_params)
if #comment.save
flash[:success] = "Komentarz dodano"
redirect_to root_path }
else
render 'staticpages#home'
end
end
Part of the home.html.erb which lists all anouncements and under each of them it adds a form to add a comment:
<% #announcements.each do |announcement| %>
.... some code ....
<% if current_user && user_signed_in? %>
<div class="create_comment" >
<%= render partial: 'shared/create_comments_form', locals: {announcement: announcement } %>
</div>
<% end %>
... some code ...
<% end %>
And _create_comment.html.erb :
<%= form_for announcement.comments.create, url: announcement_comments_path(announcement.id) do |form| %>
<%= form.label :author, "#{current_user.username}:" %>
<%= form.hidden_field :author, value: current_user.username %>
<%= form.hidden_field :user_id, value: current_user.id %>
<%= form.text_field :content, class: "form-control content_length" %>
<div class="char_counter">255</div>
<%= form.submit "Dodaj!", class: "btn btn-primary" %>
<% end %>
My question is there a better way of writing this form, because It just doesn`t look rails for me when I have to specify everywhere all those parameters. Eg. when I send parameters to _create_comment I have to pass announcement object, and in form it self I have to specify the url as it looks for create_comment_path by default.
I think you wanted just to handle nested resources, and need a form to create such a nested resource.
Then this should work:
form_for( [announcement, announcement.comments.new] ) do |form|
Do not use create in the form template, as it actually saves it to the database, you end with lots of empty comments just because somebody viewed the form.
You can use cokoon gem for this. This gem will create Dynamic nested forms using jQuery.
Also I have one more suggestion. Rather then using only you can use except. Because you have used all 6 routes without index.
root 'static_pages#home'
resources :announcements, except: [:index] do
resources :comments, only: [:create, :destroy]
end
Update:
You can use like below:
Form:
<%= form_for :comments do |form| %>
<%= form.label :author, "#{current_user.username}:" %>
<%= form.hidden_field :author, value: current_user.username %>
<%= form.hidden_field :user_id, value: current_user.id %>
<%= form.text_field :content, class: "form-control content_length" %>
<div class="char_counter">255</div>
<%= form.submit "Dodaj!", class: "btn btn-primary" %>
<% end %>
For more info: http://www.sitepoint.com/complex-rails-forms-with-nested-attributes/

Couldn't find User without an ID when calling method

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

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 4 how to pass post_id to the db

i have some problems with my app, i have posts, posts has_many responces
when i create new responce to the post, not added in the db 'responce' post_id
my routes.rb
resources :categories do
resources :posts
end
resources :posts do
resources :responces
end
controller
class ResponcesController < ApplicationController
def new
#post = Post.find(params[:post_id])
#responce = #post.responces.new(post_id:params[:post_id])
end
def create
#responce = current_user.responces.build(responce_params)
#post = Post.find(params[:post_id])
if #responce.save
flash[:success] = "Вы откликнулись на задание"
redirect_to post_path #post
else
render 'new'
end
end
def show
end
private
def responce_params
params.require(:responce).permit(:price, :comment, :post_id)
end
end
view
<%= form_for([#post, #responce]) do |f| %>
<%= f.text_area :price %>
<%= f.submit "GO", class: "btn btn-large btn-primary" %>
<% end %>
but if add to the view this
<%= f.collection_select :post_id, Post.all, :id, :name %>
rails create post_id to the db
help
You are doing several things the wrong way.
First: I don't think you need two separate resources for the same model. I'd recomend nesting all three resources upon each other like this.
resource :categories do
resource :posts do
resource :responces
end
end
This way you'll be able to find the needed category_id and post_id in the params hash.
I'd also recomend adding :shalow => true to the :categories resource to make your routes a bit prettier.
Second: you need to assign the params[:post_id] in your create action, like this.
#responce = current_user.responces.build(responce_params)
#responce.post_id = params[:post_id]
#post = #responce.post
Alternatevely you can just add a hidden field to your form like I show below, but it I don't like that approach, 'cause it can lead to security risks.
<%= form_for([#post, #responce]) do |f| %>
<%= f.text_area :price %>
<%= f.hidden_field :post_id, :value => #post.id %>
<%= f.submit "GO", class: "btn btn-large btn-primary" %>
<% end %>
In your form you aren't passing in the post_id. You probably want something like this:
<%= form_for([#post, #responce]) do |f| %>
<%= f.text_area :price %>
<%= f.hidden_field :post_id, :value => #post.id %>
<%= f.submit "GO", class: "btn btn-large btn-primary" %>
<% end %>
The hidden field will pass the id of the current post into your form as the post_id parameter.

Resources