Rails 4.0 ActiveRecord::RecordNotFound - ruby-on-rails

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?

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| %>

Custom POST routes for create action not working

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!

NoMethodError in Jobs#show

I've been stuck on this all day. When I try to show the details of a job, create a job, or edit a current job in my ruby on rails project I get a NoMethodError in Jobs#show on the second last line explaining there is a problem with the link to the edit page.
Jobs/show.html
<p id="notice"><%= notice %></p>
<p>
<strong>Name:</strong>
<%= #job.name %>
</p>
<p>
<strong>Employer:</strong>
<%= #job.employer %>
</p>
<p>
<strong>Sector:</strong>
<%= #job.sector_id %>
</p>
<p>
<strong>Experience req:</strong>
<%= #job.experience_req %>
</p>
<p>
<strong>Job info:</strong>
<%= #job.job_info %>
</p>
<h2>Star comment: </h2>
<%=form_for([#job, Request.new]) do |f| %>
</h3></br>
<%= f.text_area:content, :rows => 4, :cols=> 40%>
<div class = "actions">
<%=f.submit "Make a request for the job"%>
</div>
<% end %>
<%if #job.requests.empty? %>
<h3> You are the first to Request</h3>
<% else %>
<h2> Who else had made a request for this job:</h2>
<% #job.requests.reverse.each do |request| %>
<p><%= request.content %>
Posted <%=time_ago_in_words(request.created_at)%> ago by
<%=request.candidate.can_name%></p>
<% end %>
<% end %>
<%= link_to 'Edit', edit_jobs_path(#job) %> | **This line highlights an error**
<%= link_to 'Back', jobs_path %>
Jobs/edit.html
<h1>Editing job</h1>
<%= render 'form' %>
<%= link_to 'Show', #job %> |
<%= link_to 'Back', jobs_path %>
Routes
Rails.application.routes.draw do
# get 'sessions/new'
# get 'sessions/create'
#get 'sessions/destroy'
controller :sessions do
get 'login' =>:new
post 'login' =>:create
get 'logout' =>:destroy
delete 'logout' =>:destroy
end
#get 'pages/home'
#get 'pages/about'
resources :candidates
resources :requests
resources :employers
resources :jobs
resources :sectors
# The priority is based upon order of creation: first created -> highest
# priority.
# See how all your routes lay out with "rake routes".
# You can have the root of your site routed with "root"
root 'pages#home'
#root :to=>'pages#home
#'welcome#index'
resources :jobs do
resources :requests
end
end
Jobs_Controller
class JobsController < ApplicationController
before_action :set_job, only: [:show, :edit, :update, :destroy]
# GET /jobs
# GET /jobs.json
def index
#jobs = Job.all
end
# GET /jobs/1
# GET /jobs/1.json
def show
end
# GET /jobs/new
def new
#job = Job.new
end
# GET /jobs/1/edit
def edit
end
# POST /jobs
# POST /jobs.json
def create
#job = Job.new(job_params)
respond_to do |format|
if #job.save
format.html { redirect_to #job, notice: 'Job was successfully created.'
}
format.json { render :show, status: :created, location: #job }
else
format.html { render :new }
format.json { render json: #job.errors, status: :unprocessable_entity
}
end
end
end
# PATCH/PUT /jobs/1
# PATCH/PUT /jobs/1.json
def update
respond_to do |format|
if #job.update(job_params)
format.html { redirect_to #job, notice: 'Job was successfully updated.'
}
format.json { render :show, status: :ok, location: #job }
else
format.html { render :edit }
format.json { render json: #job.errors, status: :unprocessable_entity }
end
end
end
# DELETE /jobs/1
# DELETE /jobs/1.json
def destroy
#job.destroy
respond_to do |format|
format.html { redirect_to jobs_url, notice: 'Job was successfully
destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_job
#job = Job.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white
#list through.
def job_params
params.require(:job).permit(:name, :employer, :sector_id,
:experience_req,:job_info)
end
end
Update
Ursus informed me I had to change <%= link_to 'Show', #job %> to<%= link_to 'Show', job_path(#job) %> in Jobs/edit.html. I did this, however when I try to create a new job or edit a current job I still get the same error but the new job is still created?
This
<%= link_to 'Show', #job %>
should be
<%= link_to 'Show', job_path(#job) %>

Rails Instance Variables

I'm working on creating a survey app where surveys can have many questions and questions can have many surveys. What I'd like to do is on the survey show page display a button "Add new question" that allows a user to add a new question to that survey. So in my code I send the survey id like this:
<%= link_to "Add Question", new_question_path(:survey_id => #survey.id)%>
Then I can set #survey using the params I'm sending in my question controller. This is working fine in my :new method, but is throwing a nil error when I try to call in the :create method. I believe this is because a new instance of the controller is getting created which no longer has access to the :survey_id param I sent initially.
So I'm wondering if there is anyway to pass along the params to the next instance of the controller? Or is there a better way to send which survey should be set for that question? Is this something I could "save" in a hidden field? I thought about trying to save something in my model, but to save a question earlier would require me to remove the validations I have.
Here's my question_controller:
class QuestionsController < ApplicationController
before_action :set_question, only: [:show, :edit, :update, :destroy]
before_action :set_survey, only: [:new, :create]
# GET /questions
# GET /questions.json
def index
#questions = Question.all
end
# GET /questions/1
# GET /questions/1.json
def show
#answers = #question.answers
end
# GET /questions/new
def new
#question = Question.new
end
# GET /questions/1/edit
def edit
end
# POST /questions
# POST /questions.json
def create
#question = Question.new(question_params)
respond_to do |format|
if #question.save
#survey.questions << #question
format.html { redirect_to #question, notice: 'Question was successfully created.' }
format.json { render action: 'show', status: :created, location: #question }
else
format.html { render action: 'new' }
format.json { render json: #question.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /questions/1
# PATCH/PUT /questions/1.json
def update
respond_to do |format|
if #question.update(question_params)
format.html { redirect_to #question, notice: 'Question was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #question.errors, status: :unprocessable_entity }
end
end
end
# DELETE /questions/1
# DELETE /questions/1.json
def destroy
#question.destroy
respond_to do |format|
format.html { redirect_to questions_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_question
#question = Question.find(params[:id])
end
def set_survey
#survey = Survey.find(params[:survey_id])
flash[:alert] = "Survey is " + #survey.to_s
end
# Never trust parameters from the scary internet, only allow the white list through.
def question_params
params.require(:question).permit(:title, :single_response, :surveys, :surveytizations)
end
end
And the form I'm creating the question with:
<%= form_for(#question) do |f| %>
<% if #question.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#question.errors.count, "error") %> prohibited this question from being saved:</h2>
<ul>
<% #question.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :title %><br>
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :single_response %><br>
<%= f.check_box :single_response %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Thanks! Any help is very much appreciated!
UPDATE:
I was able to work using Rails.cache.write/Rails.cache.read - How to pass values between controller methods
Is there anything wrong with doing it that way or is that the best route?
I think you need to store the survey_id in a hidden field. Then you can access it from the questions controller. In your view:
<%= form_for(#question) do |f| %>
<%= f.hidden_field :survey_id %>
#rest of form
You also might have to change your new action to something like this:
#question = Question.new(:survey_id => params[:survey_id])
If the questions always belongs to a survey it could be a good idea to nest the routes so that you always can check which survey you are working on.

Ruby on Rails form_for reference class id and pass to child comment

I have a class called "questions", which is similar to an article, and each of them can have comments. Now the problem is, that I want to show multiple questions on the index page and all displaying the comments of the specific question as well as a small little form to leave a comment, which should be added to its question. Basically I have added the form and done everything, apart from figuring out how to get the question id and pass it to the comment.
I have made a little screenshot as well: http://prntscr.com/2pjk0i
questions_controller.rb
class QuestionsController < ApplicationController
before_action :set_question, only: [:show, :edit, :update, :destroy]
# GET /questions
# GET /questions.json
def index
#current_user ||= User.find_by_id(session[:user_id])
#questions = Question.all
end
# GET /questions/1
# GET /questions/1.json
def show
end
# GET /questions/new
def new
#question = Question.new
end
# GET /questions/1/edit
def edit
end
# POST /questions
# POST /questions.json
def create
#question = Question.new(question_params)
#current_user ||= User.find_by_id(session[:user_id])
#question.update(:user_id => #current_user.id)
respond_to do |format|
if #question.save
format.html { redirect_to #question, notice: 'Question was successfully created.' }
format.json { render action: 'show', status: :created, location: #question }
else
format.html { render action: 'new' }
format.json { render json: #question.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /questions/1
# PATCH/PUT /questions/1.json
def update
respond_to do |format|
if #question.update(question_params)
format.html { redirect_to #question, notice: 'Question was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #question.errors, status: :unprocessable_entity }
end
end
end
# DELETE /questions/1
# DELETE /questions/1.json
def destroy
#question.destroy
respond_to do |format|
format.html { redirect_to questions_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_question
#question = Question.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def question_params
params.require(:question).permit(:title, :body)
end
end
comments_controller.rb
class CommentsController < ApplicationController
before_action :set_comment, only: [:show, :edit, :update, :destroy]
# GET /comments
# GET /comments.json
def index
#current_user ||= User.find_by_id(session[:user_id])
#comments = Comment.all
end
# GET /comments/1
# GET /comments/1.json
def show
end
# GET /comments/new
def new
#comment = Comment.new
end
# GET /comments/1/edit
def edit
end
# POST /comments
# POST /comments.json
def create
#comment = Comment.new(comment_params)
#current_user ||= User.find_by_id(session[:user_id])
#comment.update(:user_id => #current_user.id, :question_id => ?) # What to add here to get the specific question id?
respond_to do |format|
if #comment.save
format.html { redirect_to '/', notice: 'comment was successfully created.' }
format.json { render action: 'show', status: :created, location: #comment }
else
format.html { render action: 'new' }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /comments/1
# PATCH/PUT /comments/1.json
def update
respond_to do |format|
if #comment.update(comment_params)
format.html { redirect_to '', notice: 'comment was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
# DELETE /comments/1
# DELETE /comments/1.json
def destroy
#comment.destroy
respond_to do |format|
format.html { redirect_to '' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_comment
#comment = Comment.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def comment_params
params.require(:comment).permit(:title, :body)
end
end
index.html.erb
<h1>Listing questions</h1>
<%= link_to 'New Question', new_question_path %>
<hr>
<% #questions.each do |question| %>
<!-- Author -->
<%= question.user.name %> <br>
<!-- Date -->
<%= question.created_at %> <br>
<!-- Title -->
<%= question.title %> <br>
<!-- Body -->
<%= question.body %> <br>
<%= question.id %> <br>
<!-- Comment count -->
<%= question.comments.size %> Comment <br>
<!-- Comments -->
<% question.comments.each do |comment| %>
<!-- Comment Author -->
<%= comment.user.name %> <br>
<!-- Comment Date -->
<%= comment.created_at %> <br>
<!-- Comment Body -->
<%= comment.body %> <br>
<% end %>
<%= form_for(question.comments.new) do |f| %>
<div class="field">
<%= f.label :body %><br>
<%= f.text_area :body %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
<hr>
<% end %>
Thank you in advance for your help! :)
The form_for will need to submit the question_id somehow - either by a route or through the form. I recommend a route.
If you don't interact with comments independently - if there is always a question, then change your routes to something like this:
resources :questions do
resources :comments
end
Then - in your form for, you will do this
<%= form_for [question, question.comments.new] do |f| %>
This will cause the form to submit (POST) to /question/:question_id/comments and you can handle it from there.
In the comments controller - you'll get the question from the params[:question_id] and return the result via an ajax response (respond to json).
This part is still tricky if you haven't done it before. If you need help with that part, you can probably find good examples or ask a separate question...
you can add hidden field inside your form
<%= f.hidden_field :question_id, value: question.id %>
or you can change your form
<%= form_for :comment, :url => comments_path(question_id:question.id) do |f| %>
<div class="field">
<%= f.label :body %><br>
<%= f.text_area :body %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
when u submit this form u will have url like /comments?question_id=id

Resources