Custom POST routes for create action not working - ruby-on-rails

Explaining the context
"I am learning Rails, building asocial app f
"I think my problem with the routes...
"...still figuring them out.
" 3 days trying all sorts of things.
"This is where I am now, and something is not working as expected.
"Any help/pointers would be appreciated! :)
The Problem
After sign in with devise i route to the main page called '/opinions"
When I access the form to create a new forum and I hit submit, "
the form post to '/opinions' correctly "
but I am rendering the same form in my user page '/users/1"
When i hit submit there i git this error ."
## The log
Started POST "/users/2" for ::1 at 2020-10-22 00:05:18 +0300
ActionController::RoutingError (No route matches [POST] "/users/2"):
## config/routes.rb
resources :followers
devise_for :users
devise_scope :user do
root to: 'devise/sessions#new'
end
resources :users, only: [:index, :show, :create]do
resources :followers, only: [:create, :destroy]
end
resources :opinions
## _form.html.erb
<%= form_with(model: #opinions, local: false) do |form| %>
<div class="field rich p-3">
<div class="control">
<%= form.rich_text_area :body, label: "What's Your Opinion", input_html: {class: "textarea"}, wrapper: false, label_html: {class: "label"}, placeholders: "Your opinion...", autofocuse: true %>
</div>
</div>
<%= form.button :submit, class: "button is-info" %>
<% end %>
## Rake Routes
root GET / devise/sessions#new
user_followers POST /users/:user_id/followers(.:format) followers#create
user_follower DELETE /users/:user_id/followers/:id(.:format) followers#destroy
users GET /users(.:format) users#index
POST /users(.:format) users#create
user GET /users/:id(.:format) users#show
opinions GET /opinions(.:format) opinions#index
POST /opinions(.:format) opinions#create
new_opinion GET /opinions/new(.:format) opinions#new
edit_opinion GET /opinions/:id/edit(.:format) opinions#edit
opinion GET /opinions/:id(.:format) opinions#show
PATCH /opinions/:id(.:format) opinions#update
## opinions_controller
def create
#opinion = #user.opinions.build(opinion_params)
respond_to do |format|
if #opinion.save
format.html { redirect_to opinions_url, notice: 'Post was successfully created.' }
format.json { render :show, status: :created, location: #opinion }
else
format.html { render :new }
format.json { render json: #opinion.errors, status: :unprocessable_entity }
end
end
end
## users_controller
class UsersController < ApplicationController
include TheUser
include ActionText::Attachable
before_action :set_user
before_action :authenticate_user!
before_action :user_signed_in?
def index
#users = User.all
#mutual_friends = User.where(id: show_two_friends)
end
def show
#user = User.find(params[:id])
#opinion = #user.opinions
respond_to do |format|
if #user
format.html
format.js { #current_user = #user }
format.json { render :show, status: :created, location: #user }
else
format.html { render :new }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
end
What am I doing wrong please help me?

Well, the error is dispatched because you should not make a POST to /resource/:id (/users/2). In case you expect to update info use PUT. I think that you are passing #opinions to form_with helper, which I guess is an array of Opinion of a user. If so, you should create a variable #opinion = Opinion.new to execute correctly in the user views. But please edit the post with the UserController.rb file to help you better.
A correct way should be like this:
##UserController.rb
...
def show ## I will guess that you are using Opinion form in User Show
#user = User.find(:id)
#opinions = #user.opinions
#new_opinion = Opinion.new
end
...
## app/views/users/show.html.erb
...
<%= form_with(model: #new_opinion, local: false) do |form| %>
<%= render 'opinions/form' form: form %>
<% end %>
...
## app/views/opinions/_form.html.erb
...
<div class="field rich p-3">
<div class="control">
<%= form.rich_text_area(
:body,
label: "What's Your Opinion",
input_html: {class: "textarea"},
wrapper: false,
label_html: {class: "label"},
placeholders: "Your opinion...",
autofocuse: true
) %>
</div>
...
</div>
...
<%= form.button :submit, class: "button is-info" %>
...
Remember, the form partial should not contain the form_with tag. Use local variables of render tag to pass the form attribute.
Hope I help. Good Luck!

Related

Rails 6 - 'missing required keys: [:post_id]' when trying to render a 'comment' form directly on my posts#index view

I've been trying to build a facebook/blog type app where comments show directly under new posts, and you can also POST a new comment by rendering a form directly under the corresponding Post. As you'll learn in the rest of my post, I'm fairly new to Rails so any resources that directly help me understand the issue I'm having (even if it's just pointing me to the right parts of the Rails docs) would be super helpful.
As of right now, my homepage renders the post#index action, as well as a a post form so that you can create new posts directly on the index page. All of this works fine until I try to render my comment form. As a note, I'm only focusing on creating a new comment before implementing editing and deleting (not that that should affect anything I wouldn't think).
Unfortunately I keep getting this error -
Moreover, when I split each of these pages into a more traditional, link_to XXXX_path style where every form and action is on its own url page, everything works fine. I think there might be something fundamental that I'm just not understanding. So, before showing my code I'll just give a quick explanation of my understanding of how I expect things to work in my app
On the index.html.erb view:
Render the index page
Show each individual post and any corresponding info I want to display with my each method.
pass the specific instance of Post using <%= render 'comment_form', :post => post %>. This should also give me access to all of the params of said instance of post in my _comment_form.html.erb partial.
On the _comment_form.html.erb partial:
add model: [post, #comment] (as my comment controller is nested in post) so that Rails knows to build a new comment with the associated post instance that was pushed through my index view.
At the end of the day, if I had to guess, my issue is with my controllers - I feel like I've put the correct code in the methods/actions, but my hunch is that there's something conflicting between the #post instance variable and the post instance being iterated over in my each method. I'm really not sure what the problem is and any help would be much appreciated. I hope I didn't over (or under) explain my problem. Thanks for the help in advance!
views/posts/index.html.erb
<p id="notice"><%= notice %></p>
<nav>
</nav>
<h1>Posts</h1>
<table>
<thead>
<tr>
<th>User</th>
<th>Body</th>
<th colspan="3"></th>
</tr>
</thead>
<%= render 'form' %>
<tbody>
<% #posts.each do |post| %>
<tr>
<td><%= link_to post.user.email, user_path(post.user_id) %></td>
<td><%= post.body %></td>
<td><%= link_to 'Show', post %></td>
<td><%= link_to 'Edit', edit_post_path(post) %></td>
<td><%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %></td>
<td>
</tr>
<tr>
<%= render 'comment_form', :post => post %>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Post', new_post_path %>
views/posts/_comment_form.html.erb
<% if user_signed_in? %>
<%= form_with(model: [post, #comment], url: post_comments_path, method: "post", local: true) do |form| %>
<div class="field">
<%= form.label :body %>
<%= form.text_area :body %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
<% else %>
Please sign in to comment on the post!
<% end %>
posts_controller.rb
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
#before_action :authenticate_user!
# GET /posts
# GET /posts.json
def index
#posts = Post.all.order("created_at DESC")
#post = post_exists?
end
# GET /posts/1
# GET /posts/1.json
def show
end
# GET /posts/new
def new
#post = current_user.posts.build
end
# GET /posts/1/edit
def edit
end
# POST /posts
# POST /posts.json
def create
#post = current_user.posts.build(post_params)
respond_to do |format|
if #post.save
format.html { redirect_to index, notice: 'Post was successfully created.' }
format.json { render :show, status: :created, location: #post }
else
format.html { render :new }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /posts/1
# PATCH/PUT /posts/1.json
def update
respond_to do |format|
if #post.update(post_params)
format.html { redirect_to #post, notice: 'Post was successfully updated.' }
format.json { render :show, status: :ok, location: #post }
else
format.html { render :edit }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_post
#post = Post.find(params[:id])
end
# Only allow a list of trusted parameters through.
def post_params
params.require(:post).permit(:body)
end
def post_exists?
current_user.posts.build if current_user != nil
end
end
comments_controller.rb
class CommentsController < ApplicationController
def new
#post = Post.find(params[:post_id])
#comment = #post.comments.build
end
def create
#post = Post.find(params[:post_id])
#comment = #post.comments.build(comments_params)
#comment.user_id = current_user.id
respond_to do |format|
if #comment.save
format.html { redirect_to posts_path, notice: 'Post was successfully created.' }
format.json { render :show, status: :created, location: #comment }
else
format.html { render :new }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
def destroy
end
private
def comments_params
params.require(:comment).permit(:body)
end
end
routes.rb
devise_for :users, controllers: {
sessions: 'users/sessions'
}
devise_scope :user do
get '/users/sign_out' => 'devise/sessions#destroy'
end
resources :posts do
resources :comments, only: [:new, :create, :destroy]
end
resources :users
root to: 'posts#index'
Models
>user.rb
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :posts, dependent: :destroy
has_many :comments, dependent: :destroy
>post.rb
belongs_to :user
has_many :comments, dependent: :destroy
>comment.rb
belongs_to :user
belongs_to :post
The error is saying that it is missing the post_id on line 2 in your comment_form.
You got:
<%= form_with(model: [post, #comment], url: post_comments_path, method: "post", local: true) do |form| %>
The url is set to post_comments_path but it doesn't knows which post so you need to pass the post to it as an argument like so:
<%= form_with(model: [post, #comment], url: post_comments_path(post), method: "post", local: true) do |form| %>
Although this will probably solve the current error, you will hit another error since you also got #comment in the comment_form and in your posts#index you don't declare #comment. You also can't declare #comment because it is depending on the post. You could try to solve that with:
<%= form_with(model: [post, post.comments.new], url: post_comments_path, method: "post", local: true) do |form| %>

ID param not being sent to Controller when manually changing routes

I have looked through the other answers provided on StackOverflow, and none of them answered my question. Here is what is happening with my code.
Error
undefined method `update' for nil:NilClass
Problem:
It looks like the param id is not being sent to the controller from the form as they show up as nil in the console using byebug.
console readout:
(byebug) params[:id]
nil
(byebug) #support
nil
(byebug) params[:title]
nil
(byebug) params[:support]
<ActionController::Parameters {"title"=>"Test", "subtitle"=>"testing",
"website"=>"www.test.com", "type_of_support"=>"", "description"=>""}
permitted: false>
(byebug) params[:support][:id]
nil
(byebug) params[:support][:title]
"Test"
I do not believe that the problem is with the form as it is the same form partial used for the new/create action and the params are sent to the controller then and the object is created (though in that case there is no id, since it is generated when creating the object, not passed from the form).
You can see in my code below that the route for PATCH is just 'support' without the :id param. If I try to add that to the route, I get an error stating that there is no route matching 'support/'. So, I have to take away the :id param in the route for it to pass the information to the controller.
I am at a loss here. How do I pass the :id to the controller? How does rails do this? Before I manually change the routes, the automatic routes from resources :supports includes an :id param for the PATCH route and it works. What am I doing wrong that it won't allow me to add that to the route?
Code:
config/routes.rb
get 'support', as: 'supports', to: 'supports#index'
post 'support', to: 'supports#create'
get 'support/new', as: 'new_support', to: 'supports#new'
get 'support/:id/edit', as: 'edit_support', to: 'supports#edit'
get 'support/:title', as: 'support_page', to: 'supports#show'
patch 'support/', to: 'supports#update'
put 'support/:id', to: 'supports#update'
delete 'supports/:id', to: 'supports#destroy'
Results this for rake routes:
supports GET /support(.:format) supports#index
support POST /support(.:format) supports#create
new_support GET /support/new(.:format) supports#new
edit_support GET /support/:id/edit(.:format) supports#edit
support_page GET /support/:title(.:format) supports#show
PATCH /support(.:format) supports#update
PUT /support/:id(.:format) supports#update
DELETE /supports/:id(.:format) supports#destroy
app/controllers/supports_controllers.rb
class SupportsController < ApplicationController
before_action :set_support_by_title, only: [:show]
before_action :set_support_by_id, only: [:edit, :update, :destroy]
def index
#supports = Support.all
end
def show
end
def new
#support = Support.new
end
def edit
end
def create
#support = Support.new(support_params)
respond_to do |format|
if #support.save
format.html { redirect_to #support,
notice: 'Support was successfully created.' }
else
format.html { render :new }
end
end
end
def update
# byebug
respond_to do |format|
if #support.update(support_params)
format.html { redirect_to #support,
notice: 'Support was successfully updated.' }
else
format.html { render :edit }
end
end
end
def destroy
#support.destroy
respond_to do |format|
format.html { redirect_to supports_url,
notice: 'Support was successfully destroyed.' }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_support_by_title
#support = Support.find_by(title: params[:title])
# byebug
end
def set_support_by_id
#support = Support.find(params[:id])
# byebug
end
# Never trust parameters from the scary internet,
# only allow the white list through.
def support_params
params.require(:support).permit(:title,
:subtitle,
:website,
:type_of_support,
:description)
end
end
app/views/supports/edit.html.erb
<h1>Editing Support</h1>
<%= render 'form', support: #support %>
<%= link_to 'Show', support_page_path(#support.title) %> |
<%= link_to 'Back', supports_path %>
app/views/supports/_form.html.erb
<%= form_with(model: support, local: true) do |form| %>
<% if support.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(support.errors.count, "error") %>
prohibited this support from being saved:
</h2>
<ul>
<% support.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
Title:
<%= form.text_field :title, id: :support_title %>
</div>
<div class="field">
Subtitle:
<%= form.text_field :subtitle, id: :support_subtitle %>
</div>
<div class="field">
Website:
<%= form.text_field :website, id: :support_website %>
</div>
<div class="field">
Type of Support:
<%= form.text_field :type_of_support, id: :support_type %>
</div>
<div class="field">
Description:
<%= form.text_area :description, id: :support_description %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
While writing this question, I thought of something and tried it. And it worked. Instead of re-writing all of the routes myself, I wrote only 2 and used the resources :supports, except: [:index, :show] to have rails generate the others. This solved my issue.
Explanation
I knew that something was going on behind the scenes that I did not understand. The entire process worked fine before I started to change the routes. So, something in there was incorrect. (I still don't know what it is and how to change it.)
The only two routes that I really want to be changed are the two that users see. I don't care about how the routes look in the admin backend. So, that meant that I only needed to change the routes for index and show to be SEO friendly and look better in the browser. So, to do that I wrote the routes like this:
config/routes.rb
resources :supports, except: [:index, :show]
get 'support', as: 'support_index', to: 'supports#index'
get 'support/:title', as: 'support_page', to: 'supports#show'
This then created all of the new, create, edit, update, destroy routes for me. After doing this, this is how my routes now look:
supports POST /supports(.:format) supports#create
new_support GET /supports/new(.:format) supports#new
edit_support GET /supports/:id/edit(.:format) supports#edit
support PATCH /supports/:id(.:format) supports#update
PUT /supports/:id(.:format) supports#update
DELETE /supports/:id(.:format) supports#destroy
support_index GET /support(.:format) supports#index
support_page GET /support/:title(.:format) supports#show
As you can see, the PATCH route is now getting the param :id to be able to update the record.
Now, I just had to change a few of the redirects in the controller after create, update and destroy like this:
def create
#support = Support.new(support_params)
respond_to do |format|
if #support.save
format.html { redirect_to support_page_path(title: #support.title),
notice: 'Support was successfully created.' }
else
format.html { render :new }
end
end
end
def update
respond_to do |format|
if #support.update(support_params)
format.html { redirect_to support_page_path(title: #support.title),
notice: 'Support was successfully updated.' }
else
format.html { render :edit }
end
end
end
def destroy
#support.destroy
respond_to do |format|
format.html { redirect_to support_index_path,
notice: 'Support was successfully deleted.' }
end
end
These redirect_to statements now match the routes that I generated for index and show.
And now everything works.
So, problem solved, though I still don't know what I was doing wrong before. Any light that can be shed would be appreciated.

Rails - associations, feedback on users by users - showing feedback

I'm struggling to figure out how to set up my rails evaluation model so that users can use it to leave feedback on other users.
I outlined the key part of my problem in this post:
Rails - feedback on specific users, how to set up the form to identify relevant users
The suggestion I received from that was to set up the model as follows:
User.rb
has_many :given_evaluations, foreign_key: :evaluator_id, dependent: :destroy, class_name: Evaluation
has_many :received_evaluations, foreign_key: :evaluatee_id, dependent: :destroy, class_name: Evaluation
Evaluation.rb
belongs_to :evaluator, foreign_key: :evaluator_id, class_name: User
belongs_to :evaluatee, foreign_key: :evaluatee_id, class_name: User
Evaluation Controller
class EvaluationsController < ApplicationController
before_action :set_evaluation, only: [:show, :edit, :update, :destroy]
# before_filter :get_user, only: [:show, :edit, :update, :destroy]
# GET /evaluations
# GET /evaluations.json
def index
# #evaluations = Evaluation.all
#given_evaluations = current_user.given_evaluations
#received_evaluations = current_user.received_evaluations
end
# GET /evaluations/1
# GET /evaluations/1.json
def show
# #received_evaluations = #user.received_evaluations
#evaluation = current_user.received_evaluations.find_by(id: params[:id]) || current_user.given_evaluations.find(params[:id])
# #received_evaluation = current_user.received_evaluations.find params[:id]
end
# GET /evaluations/new
def new
#evaluation = Evaluation.new
end
# GET /evaluations/1/edit
def edit
end
# POST /evaluations
# POST /evaluations.json
def create
# #evaluation = Evaluation.new(evaluation_params)
#evaluation = current_user.given_evaluations.build(evaluation_params)
respond_to do |format|
if #evaluation.save
format.html { redirect_to #evaluation, notice: 'Evaluation was successfully created.' }
format.json { render :show, status: :created, location: #evaluation }
else
format.html { render :new }
format.json { render json: #evaluation.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /evaluations/1
# PATCH/PUT /evaluations/1.json
def update
current_user.given_evaluations.find(params[:id])
respond_to do |format|
if #evaluation.update(evaluation_params)
format.html { redirect_to #evaluation, notice: 'Evaluation was successfully updated.' }
format.json { render :show, status: :ok, location: #evaluation }
else
format.html { render :edit }
format.json { render json: #evaluation.errors, status: :unprocessable_entity }
end
end
end
# DELETE /evaluations/1
# DELETE /evaluations/1.json
def destroy
current_user.given_evaluations.find(params[:id])
#evaluation.destroy
respond_to do |format|
format.html { redirect_to evaluations_url, notice: 'Evaluation was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_evaluation
#evaluation = Evaluation.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def evaluation_params
params[:evaluation].permit(:overall_score, :project_score, :personal_score, :remark, :work_again?, :continue_project?, :evaluatee_id)
end
end
Evaluation form
<%= simple_form_for(#evaluation) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.select :evaluatee_id, User.all.map{|u| [u.formal_name, u.id]} %>
<%= f.input :overall_score, collection: 1..10, autofocus: true, :label => "How do you rate this project experience (1 being did not meet expectations - 10 being met all expectations) ?" %>
<%= f.input :continue_project?, as: :boolean, checked_value: true, unchecked_value: false, :label => "Do you intend to continue working on the project?" %>
<%= f.input :remark, as: :text, :label => "Evaluate your experience", :input_html => {:rows => 10} %>
</div>
<div class="form-actions">
<%= f.button :submit %>
Evaluation show view
<% #received_evaluations.each do |receval| %>
<div id="portfolioFiltering" class="masonry-wrapper row">
<%= receval.remark %>
<%#= eval.personal_score %>
<small><%= receval.created_at %></small>
</div>
<% end %>
Alternative attempt at evaluation show view
<% #given_evaluations.each do |receval| %>
<div id="portfolioFiltering" class="masonry-wrapper row">
<%= receval.remark %>
<%#= eval.personal_score %>
<small><%= receval.created_at %></small>
</div>
<% end %>
The problem I'm having now is that regardless of whether I try to show given evaluation or received evaluation in the show, I get an error message that says:
undefined method `each' for nil:NilClass
I can't figure out how to setup the model so that a user can evaluate another user. I want to show each user's received evaluation on their respective show page. i can't figure out what's going wrong. I can see from the console that a user has received evaluations as:
=> #<Evaluation id: 8, evaluatee_id: 34, overall_score: 4, project_score: 5, personal_score: 5, remark: "jhjkhjhjkhkjhjkhjhkhjhkj", work_again?: nil, continue_project?: nil, created_at: "2016-06-12 21:52:53", updated_at: "2016-06-12 21:52:53", evaluator_id: 34>
There is an entry for the user I'm working with. However, I can't find a way to show that evaluation.
The most immediate problem I could see is that the instance variables: #given_evaluations and #received_evaluations are not being set in your show actions and the commented portions are using the ActiveRecord#find method, which would return one instance therefore the reason you couldn't loop through the evaluations.
I think a better place to show all your user's evaluation is in the index action, as you're doing already, you may move the current logic for the show to the index view.
To show each user's received evaluation on the show action, you would do:
#evaluation = current_user.received_evaluations.find(params[:id])
Then in your show view, you should have something like:
<div id="portfolioFiltering" class="masonry-wrapper row">
<%= #evaluation.remark %>
<%= #evaluation.personal_score %>
<small><%= #evaluation.created_at %></small>
</div>

Sidestep Devise "You are already logged in." error with Namespaced custom controllers and views

This article explains how to let users make other users in devise. I've got it almost figured out, thanks to the answer provided in that article by Adam Waselnuk except I can't figure out how to create the same result with namespaced controllers and views. I get one of two errors, depending on how my routes.rb is set up... either Routing Error, No route matches [PUT] "/users/new" or
My code is below.
routes.rb
Rails.application.routes.draw do
namespace :admin do
resources :users, except: :create
end
post 'users/new' => 'admin/users#new', as: :create_user
resources :shows
resources :posts
resources :global_posts
devise_for :users, controllers: {
registrations: "users/registrations",
}
root 'pages#home'
get 'pages/home'
get 'admin' => 'admin#index', as: :admin
end
admin/users_controller.rb
class Admin::UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]
# GET /admin/users
# GET /admin/users.json
def index
#all_users = User.all
end
def show
end
# GET /admin/users/new
def new
#user = User.new
end
# GET /admin/users/1/edit
def edit
end
# POST /admin/users
# POST /admin/users.json
def create
#user = User.new(user_params)
end
# PATCH/PUT /admin/users/1
# PATCH/PUT /admin/users/1.json
def update
respond_to do |format|
if #user.update(user_params)
format.html { redirect_to #user, notice: 'User was successfully updated.' }
format.json { render :show, status: :ok, location: #user }
else
format.html { render :edit }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
# DELETE /admin/users/1
# DELETE /admin/users/1.json
def destroy
#user.destroy
respond_to do |format|
format.html { redirect_to root_path, notice: 'User was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_user
#user = User.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def user_params
params.require(:user).permit(
:name, :email, :password, :password_confirmation
)
end
end
And finally, the admin/users/new.html.erb
<h2>New User</h2>
<%= form_for #user, url: create_user_path, html: { method: :put } do |f| %>
<div>
<%= f.label :name %><br />
<%= f.text_field :name, autofocus: true %>
</div>
<div>
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %>
</div>
<div>
<%= f.label :password %>
<%= f.password_field :password, autocomplete: "off" %>
</div>
<div>
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<div>
<%= f.submit "Create New User" %>
</div>
<% end %>
Your route should be
post 'users' => 'admin/users#create', as: :create_user
Then you can create the user in
def create
#user = User.new(user_params)
#user.save
end

Rails 4.0 ActiveRecord::RecordNotFound

I am trying to learn Rails and am making my first app and am running into this error:
ActiveRecord::RecordNotFound in PartsController#show
Couldn't find Part with id=new_ic
with the highlighted source:
def set_part
#part = Part.find(params[:id])
end
I am brand new to rails and i can't figure out what is wrong and I can't find any help online either. The app is a part management system for electronic components. The form gets filled out and the data is saved to the database for future reference/updating. Could someone please help?
Source code time:
parts/_ic_form.html.erb
<h1>Add An IC</h1>
<%= simple_form_for #parts do |f| %>
<%= f.input :component_type, :as => :hidden, :input_html => { :value => "IC"} %>
<%= f.input :ic_model, label: 'IC Model' %>
<%= f.input :ic_manufacturer, label: 'IC Manufacturer' %>
<%= f.input :ic_pinCount, label: 'IC Pin-Count' %>
<%= f.input :ic_mountType, collection: ["Through Hole", "Surface Mount"], label: 'IC Mount Type' %>
<%= f.input :ic_package, label: 'IC Package' %>
<%= f.input :ic_quantityOnHand, label: 'Quantity On Hand' %>
<%= f.input :ic_quantityOnOrder, label: 'Quantity On Order' %>
<%= f.button :submit %>
<% end %>
parts/new_ic.html.erb
<%= render 'ic_form' %>
parts/new.html.erb
<h1>New part</h1>
<%= link_to 'IC', 'new_ic' %>
<%= link_to 'Back', parts_path %>
parts_controller.rb
class PartsController < ApplicationController
before_action :set_part, only: [:show, :edit, :update, :destroy]
before_filter :initialize_parts
def initialize_parts
#parts = Part.new
end
# GET /parts
# GET /parts.json
def index
#parts = Part.all
end
# GET /parts/1
# GET /parts/1.json
def show
end
# GET /parts/new
def new
#part = Part.new
end
# GET /parts/1/edit
def edit
end
# POST /parts
# POST /parts.json
def create
#part = Part.new(part_params)
respond_to do |format|
if #part.save
format.html { redirect_to #part, notice: 'Part was successfully created.' }
format.json { render action: 'show', status: :created, location: #part }
else
format.html { render action: 'new' }
format.json { render json: #part.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /parts/1
# PATCH/PUT /parts/1.json
def update
respond_to do |format|
if #part.update(part_params)
format.html { redirect_to #part, notice: 'Part was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #part.errors, status: :unprocessable_entity }
end
end
end
# DELETE /parts/1
# DELETE /parts/1.json
def destroy
#part.destroy
respond_to do |format|
format.html { redirect_to parts_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_part
#part = Part.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def part_params
params[:part]
end
end
routes.rb Pretty sure i screwed this one up too
Pms::Application.routes.draw do
resources :parts
resources :parts
root to: "parts#new_ic"
end
rake routes Output:
Prefix Verb URI Pattern Controller#Action
parts GET /parts(.:format) parts#index
POST /parts(.:format) parts#create
new_part GET /parts/new(.:format) parts#new
edit_part GET /parts/:id/edit(.:format) parts#edit
part GET /parts/:id(.:format) parts#show
PATCH /parts/:id(.:format) parts#update
PUT /parts/:id(.:format) parts#update
DELETE /parts/:id(.:format) parts#destroy
GET /parts(.:format) parts#index
POST /parts(.:format) parts#create
GET /parts/new(.:format) parts#new
GET /parts/:id/edit(.:format) parts#edit
GET /parts/:id(.:format) parts#show
PATCH /parts/:id(.:format) parts#update
PUT /parts/:id(.:format) parts#update
DELETE /parts/:id(.:format) parts#destroy
root GET / parts#new_ic
One problem is in this line:
<%= link_to 'IC', 'new_ic' %>
link_to should look like this:
link_to "Profile", profile_path(#profile)
#Profile is the name
#profile_path(#profile) is the link
Try this instead:
#parts/new.html.erb
<%= link_to 'IC', root_path %>
in your routes, root GET / parts#new_ic is linking to your new_ic action. I'd disagree with the way you access it (via root) - but it will work if you want to access the new_ic action. Why is this your root route, though?

Resources