I just need a link_to link that automatically updates a value.
I have done the following:
1) Added the field i want to update into the post_controller permit list:
#post_controller.rb
def post_params
params.require(:post).permit(:title, :description, :file, :user_id, :category_id, :revisor_id, :visible)
end
2) Added the link_to link in the view:
<td><%= link_to 'Publish', post_path(post, visible: true), method: :put %></td>
any idea what im doing wrong?
#routes.rb
resources :posts do
get 'revisions', on: :collection
end
the error i'm getting is:
param is missing or the value is empty: post
Here is the controller:
#posts_controller.rb
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
# GET /posts
# GET /posts.json
def index
#posts = Post.all
end
def revisions
#posts = Post.where(revisor_id: current_user.id)
end
# GET /posts/1
# GET /posts/1.json
def show
end
# GET /posts/new
def new
#post = Post.new
end
# GET /posts/1/edit
def edit
end
# POST /posts
# POST /posts.json
def create
#post = Post.new(post_params)
#post.visible = true
#post.user_id = current_user.id
#petition = Petition.new(user_id: current_user.id, category_id: #post.category_id, status: "New")
#petition.save
respond_to do |format|
if #post.save
format.html { redirect_to #post, 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
# Never trust parameters from the scary internet, only allow the white list through.
def post_params
params.require(:post).permit(:title, :description, :file, :user_id, :category_id, :revisor_id, :visible)
end
end
Here is the view:
#revisions.html.erb
<h1>Pending for revision</h1>
<table>
<thead>
<tr>
<th>Title</th>
<th>Description</th>
<th>User</th>
<th>Category</th>
<th>Revisor</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #posts.pending_posts.each do |post| %>
<tr>
<td><%= post.title %></td>
<td><%= post.description %></td>
<td><%= post.user_id %></td>
<td><%= post.category_id %></td>
<% if !post.revisor_id %>
<td> No asignado </td>
<% else %>
<td><%= post.revisor_id %></td>
<% end %>
<td><%= link_to 'Publish', post_path(post, visible: true), method: :put %></td>
<!--<td><%#= link_to 'Edit', edit_petition_path(petition) %></td>-->
<!--<td><%#= link_to 'Destroy', petition, method: :delete, data: { confirm: 'Are you sure?' } %></td>-->
</tr>
<% end %>
</tbody>
</table>
Here is the model:
#post.rb
class Post < ActiveRecord::Base
belongs_to :category
belongs_to :user
has_one :petition
scope :my_revisions, ->(user){ where("posts.user_id = ?", user.id)}
scope :visible_posts, -> {where(visible: true)}
scope :pending_posts, -> {where(visible: false)}
end
SERVER LOG:
Started PUT "/posts/12?visible=true" for 127.0.0.1 at 2014-07-16 10:07:31 +0100
Processing by PostsController#update as HTML
Parameters: {"authenticity_token"=>"authenticitytoken=", "visible"=>"true", "id"=>"12"}
Post Load (0.2ms) SELECT "posts".* FROM "posts" WHERE "posts"."id" = ? LIMIT 1 [["id", 12]]
Completed 400 Bad Request in 2ms
ActionController::ParameterMissing (param is missing or the value is empty: post):
app/controllers/posts_controller.rb:79:in `post_params'
app/controllers/posts_controller.rb:51:in `block in update'
app/controllers/posts_controller.rb:50:in `update'
Rendered /home/kbs23/.rvm/gems/ruby-2.1.0#global/gems/actionpack-4.1.2/lib/action_dispatch/middleware/templates/rescues/_source.erb (0.6ms)
Rendered /home/kbs23/.rvm/gems/ruby-2.1.0#global/gems/actionpack-4.1.2/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (1.5ms)
Rendered /home/kbs23/.rvm/gems/ruby-2.1.0#global/gems/actionpack-4.1.2/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.0ms)
Rendered /home/kbs23/.rvm/gems/ruby-2.1.0#global/gems/actionpack-4.1.2/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (13.7ms)
Here are my routes:
#rake routes
revisions_posts GET /posts/revisions(.:format) posts#revisions
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
I finally got to fix this by just changing the link from:
<td><%= link_to 'Publish', post_path(post, visible: true), method: :put %></td>
to this:
<td><%= link_to 'Publish', post_path(post, post: {visible: :true}), method: :put %></td>
Related
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| %>
So my goal with this method is to have it link to customers/1/showcar similar to how it will link to customers/1/edit, which is how I'm attempting to model my code.
My controller is
class CustomersController < ApplicationController
before_action :set_customer, only: [:show, :edit, :update, :destroy, :showcar]
# GET /customers
# GET /customers.json
def index
#customers = Customer.all
end
# GET /customers/1
# GET /customers/1.json
def show
end
# GET /customers/1/showcar
def showcar
end
# GET /customers/new
def new
#customer = Customer.new
end
# GET /customers/1/edit
def edit
end
# POST /customers
# POST /customers.json
def create
#customer = Customer.new(customer_params)
respond_to do |format|
if #customer.save
format.html { redirect_to #customer, notice: 'Customer was successfully created.' }
format.json { render :show, status: :created, location: #customer }
else
format.html { render :new }
format.json { render json: #customer.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /customers/1
# PATCH/PUT /customers/1.json
def update
respond_to do |format|
if #customer.update(customer_params)
format.html { redirect_to #customer, notice: 'Customer was successfully updated.' }
format.json { render :show, status: :ok, location: #customer }
else
format.html { render :edit }
format.json { render json: #customer.errors, status: :unprocessable_entity }
end
end
end
# DELETE /customers/1
# DELETE /customers/1.json
def destroy
#customer.destroy
respond_to do |format|
format.html { redirect_to customers_url, notice: 'Customer was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_customer
#customer = Customer.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def customer_params
params.require(:customer).permit(:cust_id, :cust_fname, :cust_lname, :cust_phone, :cust_addr, :cust_date)
end
end
and my html.erb file where I'm attempting to call the method is
<style>
th, td{
padding-left: 20px;
}
</style>
<p id="notice"><%= notice %></p>
<h1>Customers</h1>
<table>
<thead>
<tr>
<th>Cust ID</th>
<th>Cust fname</th>
<th>Cust lname</th>
<th>Cust phone</th>
<th>Cust addr</th>
<th>Cust date</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #customers.each do |customer| %>
<% belongstocust = Car.where(cust_id: customer.cust_id) %>
<tr>
<td><%= customer.cust_id %></td>
<td><%= customer.cust_fname %></td>
<td><%= customer.cust_lname %></td>
<td><%= customer.cust_phone %></td>
<td><%= customer.cust_addr %></td>
<td><%= customer.cust_date %></td>
<td><%= link_to 'Show', customer %></td>
<td><%= link_to 'Edit', edit_customer_path(customer) %></td>
<td><%= link_to 'Destroy', customer, method: :delete, data: { confirm: 'Are you sure?' } %></td>
#placeholder, not permanent code
<% i = '' %>
<% belongstocust.each do |car| %>
<% i = car.car_model %>
<td><%= link_to 'Show ' + i, car_path(car) %></td>
<% end %>
<td><%= link_to 'Show Car', showcar_customer_path(customer) %> </td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Customer', new_customer_path %>
<br>
<%= link_to 'Home', home_index_path %>
The issue is, whenever I have the code <td><%= link_to 'Show Car', showcar_customer_path(customer) %> </td>, I get the noMethodError even though the method is defined inside the controller, and it looks the exact same as def show and def edit. I've tried making a controller called customer, and adding the showcar method to that controller, and it worked, but it wouldn't pass over the customer. I also tried adding showcar to customer.rb, but it also gave me a noMethodError. I'm a complete noob when it comes to ruby, and was just told to make a project using the framework, so I've been having to learn along the way. This could be a really simple issue that I don't know how to solve due to my ignorance, so if that's the case I'm sorry.
I get the noMethodError even though the method is defined inside the controller
No. You have showcar defined, not showcar_customer_path. You are missing a route, the thing that defines xxx_path methods.
In your config/routes.rb you probably have
resources :customers
To register this new action, you can do
resources :customers do
member do
get :showcar
end
end
Now showcar_customer_path should be available to use in the views.
i got a little annoying problem.
i use this line of code on my homepage and it works, but on my posts/index page it doesn't work.
<%= link_to post.title, user_post_path(post.user.user_name, post), class:"post-listing-home-title" %>
Ultimately i want to render all posts from users on the post index page, linking to their post assosicated like this
localhost:3000/users/user_name/posts/"name of the post"
here is my error
Showing /Users/****/rorapps/*****/app/views/posts/index.html.erb where line #10 raised:
No route matches {:action=>"show", :controller=>"posts", :id=>"eli-the-great", :user_id=>nil} missing required keys: [:user_id]
here is my code
Posts controller
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
# GET /posts
# GET /posts.json
def index
#posts = Post.all.order("created_at desc")
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
flash[:notice] = "Post successfully created"
format.html { redirect_to #post }
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)
flash[:notice] = "Post successfully created"
format.html { redirect_to #post }
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 }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_post
#post = Post.friendly.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def post_params
params.require(:post).permit(:title, :content,:slug, :metadescription, :focuskeyword)
end
end
posts/index.html.erb
<p id="notice"><%= notice %></p>
<h1 class="post-listing">Listing Posts</h1>
<% #posts.each do |post| %>
<p class="date"><%= post.created_at.strftime('%A, %B %d') %></p>
<%= link_to post.title, user_post_path(post.user.user_name, post), class:"post-listing-title" %>
<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>
<% end %>
welcome.html.erb again this is where the line of code works
<div class="container">
<% #posts.each do |post| %>
<div class="featured-post fadeInBlock animated">
<p class="date"><%= post.created_at.strftime('%A, %B %d') %></p>
<span class="show-right"><%= link_to '', user_post_path(:user_id, post), class:"myright fa fa-chevron-right" %></span>
<%= link_to post.title, user_post_path(post.user.user_name, post), class:"post-listing-home-title" %>
<% if user_signed_in? %>
<td><%= link_to 'Edit', edit_user_post_path(:user_id,post) %></td>
<td><%= link_to 'Destroy', user_post_path(:user_id, post), method: :delete, data: { confirm: 'Are you sure?' } %></td>
<% end %>
</div>
<% end %>
<div id="about-home">
<div id="about-box">
<h1 id="abouttext">Try Harder !</h1>
</div>
</div>
Thank you everyone for your help
The problem is with this line
<%= link_to post.title, user_post_path(post.user.user_name, post), class:"post-listing-title" %>
You are render these links inside a loop
<% #posts.each do |post| %>
So its seems like one of your post author doesn't has user_name.
I am trying to add Searchkick gem in my app with Ruby on Rails but when i type a word in my search box i get this error in my app. I have installed elasticsearch and the latest version of java as required but still the error is the same. This is the error i am getting :
Faraday::ConnectionFailed in PostsController#search
Connection refused - connect(2) for "localhost" port 9200
Here's my code:
The Terminal shows that elastic search is installed:
Terminal
Warning: elasticsearch-1.7.3 already installed
posts_controller.rb
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
def search
if params[:search].present?
#posts = Post.search(params[:search])
else
#posts = Post.all
end
end
# GET /posts
# GET /posts.json
def index
#posts = Post.all
end
# GET /posts/1
# GET /posts/1.json
def show
end
# GET /posts/new
def new
#post = Post.new
end
# GET /posts/1/edit
def edit
end
# POST /posts
# POST /posts.json
def create
#post = Post.new(post_params)
respond_to do |format|
if #post.save
format.html { redirect_to #post, 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
# Never trust parameters from the scary internet, only allow the white list through.
def post_params
params.require(:post).permit(:name)
end
end
model/post.rb
class Post < ActiveRecord::Base
searchkick
end
views/post/index.html.erb
<p id="notice"><%= notice %></p>
<%= form_tag search_posts_path, method: :get, class: "navbar-form navbar-right", role: "search" do %>
<p>
<%= text_field_tag :search, params[:search], class: "form-control" %>
<%= submit_tag "Search", name: nil, class: "btn btn-default" %>
</p>
<% end %>
<h1>Listing Posts</h1>
<table>
<thead>
<tr>
<th>Name</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #posts.each do |post| %>
<tr>
<td><%= post.name %></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>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Post', new_post_path %>
views/search.html.erb
<table>
<thead>
<tr>
<th>Search Result</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #posts.each do |post| %>
<tr>
<td><%= post.name %></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>
</tr>
<% end %>
</tbody>
</table>
config/routes.rb
Rails.application.routes.draw do
resources :posts do
collection do
get 'search'
end
end
end
This is the screen i am getting with the error shown :
Connection refused - connect(2) for "localhost" port 9200
Looks like your elastic search service is not running. You have to make sure it's running.
To see if your elastic search service is running, run:
curl localhost:9200
If it's running, then it should return a hash like this:
{
"status" : 200,
"name" : "Buzz",
"cluster_name" : "your_cluster_name",
"version" : {
"number" : "1.4.5",
"build_hash" : "...",
"build_timestamp" : "2015-04-27T08:06:06Z",
"build_snapshot" : false,
"lucene_version" : "4.10.4"
},
"tagline" : "You Know, for Search"
}
If elastic search is not running which is most likely the case for you, start it using this command:
sudo service elasticsearch start
That should fix your problem.
I have a parent/children relationship model with nested resources setup in order to create child data under a certain parent from it's show page. However, when I click on the child's new page link from the parent page ("http://localhost:3000/brands/1/restaurants/new"), I get an error saying that "NoMethodError in...". Please help.
config/routes.rb
Rails.application.routes.draw do
resources :brands, shallow: true do
resources :restaurants
end
resources :managers
# Prefix Verb URI Pattern Controller#Action
# brand_restaurants GET /brands/:brand_id/restaurants(.:format) restaurants#index
# POST /brands/:brand_id/restaurants(.:format) restaurants#create
# new_brand_restaurant GET /brands/:brand_id/restaurants/new(.:format) restaurants#new
# edit_restaurant GET /restaurants/:id/edit(.:format) restaurants#edit
# restaurant GET /restaurants/:id(.:format) restaurants#show
# PATCH /restaurants/:id(.:format) restaurants#update
# PUT /restaurants/:id(.:format) restaurants#update
# DELETE /restaurants/:id(.:format) restaurants#destroy
# brands GET /brands(.:format) brands#index
# POST /brands(.:format) brands#create
# new_brand GET /brands/new(.:format) brands#new
# edit_brand GET /brands/:id/edit(.:format) brands#edit
# brand GET /brands/:id(.:format) brands#show
# PATCH /brands/:id(.:format) brands#update
# PUT /brands/:id(.:format) brands#update
# DELETE /brands/:id(.:format) brands#destroy
# managers GET /managers(.:format) managers#index
# POST /managers(.:format) managers#create
# new_manager GET /managers/new(.:format) managers#new
# edit_manager GET /managers/:id/edit(.:format) managers#edit
# manager GET /managers/:id(.:format) managers#show
# PATCH /managers/:id(.:format) managers#update
# PUT /managers/:id(.:format) managers#update
# DELETE /managers/:id(.:format) managers#destroy managers#destroy
end
models/brand.rb
class Brand < ActiveRecord::Base
has_many :restaurants
end
models/restaurants.rb
class Restaurant < ActiveRecord::Base
belongs_to :brand
end
controllers/restaurants_controller.rb
class RestaurantsController < ApplicationController
before_action :set_restaurant, only: [:new, :create, :show, :edit, :update, :destroy]
# GET /restaurants
# GET /restaurants.json
def index
#restaurants = Restaurant.all
end
# GET /restaurants/1
# GET /restaurants/1.json
def show
end
# GET /restaurants/new
def new
# #restaurant = Restaurant.new
#restaurant = Restaurant.new
end
# GET /restaurants/1/edit
def edit
end
# POST /restaurants
# POST /restaurants.json
def create
#restaurant = Restaurant.new(restaurant_params)
respond_to do |format|
if #restaurant.save
format.html { redirect_to brands_path, notice: 'Restaurant was successfully created.' }
format.json { render :show, status: :created, location: #restaurant }
else
format.html { render :new }
format.json { render json: #restaurant.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /restaurants/1
# PATCH/PUT /restaurants/1.json
def update
respond_to do |format|
if #restaurant.update(restaurant_params)
format.html { redirect_to #restaurant, notice: 'Restaurant was successfully updated.' }
format.json { render :show, status: :ok, location: #restaurant }
else
format.html { render :edit }
format.json { render json: #restaurant.errors, status: :unprocessable_entity }
end
end
end
# DELETE /restaurants/1
# DELETE /restaurants/1.json
def destroy
#restaurant.destroy
respond_to do |format|
format.html { redirect_to restaurants_url, notice: 'Restaurant was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_restaurant
#restaurant = Restaurant.find_by(params[:brand_id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def restaurant_params
params.require(:restaurant).permit(:name, :brand_id) if params[:restaurant]
end
end
views/brands/show.html
<p id="notice"><%= notice %></p>
<p>
<strong>Name:</strong>
<%= #brand.name %>
</p>
<p>
<strong>Manager:</strong>
<%= #brand.manager_id %>
</p>
<table>
<% #brand.restaurants.each do |restaurant| %>
<tr>
<td><%= restaurant.name %></td>
<td><%= restaurant.brand_id %></td>
<td><%= link_to 'Show', restaurant %></td>
<td><%= link_to 'Edit', edit_restaurant_path(restaurant) %></td>
<td><%= link_to 'Destroy', restaurant, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</table>
<br>
**<%= link_to 'Add New Restaurant', new_brand_restaurant_path(#brand) %>**
<%= link_to 'Edit', edit_brand_path(#brand) %> |
<%= link_to 'Back', brands_path %>
What did I do wrong?
Appreciate your help.
Addin Full Error Message:
NoMethodError in Restaurants#new Showing
/Users/kaku/sample/relation/app/views/restaurants/_form.html.erb where
line #1 raised:
undefined method `restaurants_path' for
<#:0x007fd4ec2e46e0> Extracted source (around line #1): 1 2 3 4 5 6
<%= form_for(#restaurant) do |f| %>
<% if #restaurant.errors.any? %>
<%= pluralize(#restaurant.errors.count, "error") %> prohibited this restaurant from being saved:
Trace of template inclusion: app/views/restaurants/new.html.erb
Rails.root: /Users/kaku/sample/relation
Application Trace | Framework Trace | Full Trace
app/views/restaurants/_form.html.erb:1:in
_app_views_restaurants__form_html_erb__1732550980462972679_70276222510780' app/views/restaurants/new.html.erb:3:in
_app_views_restaurants_new_html_erb___209183791776779444_70276222559000'
Request
Parameters:
{"brand_id"=>"2"} Toggle session dump
_csrf_token: "MG3xNH+mscxxPiQqLVkF011BDb5RGlWJPuTN3GiEcGo=" session_id: "e1f92f37d231a058162af62bae976ff5" Toggle env dump
GATEWAY_INTERFACE: "CGI/1.1" HTTP_ACCEPT:
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8"
HTTP_ACCEPT_ENCODING: "gzip, deflate, sdch" HTTP_ACCEPT_LANGUAGE:
"ja,en-US;q=0.8,en;q=0.6" REMOTE_ADDR: "::1" REMOTE_HOST: "::1"
SERVER_NAME: "localhost" SERVER_PROTOCOL: "HTTP/1.1" Response
Headers:
None
As you pointed in the code, I believe the error is in this line
<%= link_to 'Add New Restaurant', new_brand_restaurant_path(#brand) %>
You should have #brand in the new method of restaurants_controller
def new
#brand = Brand.find(params[:brand_id])
#restaurant = Restaurant.new
end
And also I noticed that you have defined set_restaurant wrongly. It should be
def set_restaurant
#restaurant = Restaurant.find(params[:id])
end
Update:
undefined method `restaurants_path'
You have nested resources, so this line
<%= form_for(#restaurant) do |f| %>
should be
<%= form_for [#brand, #restaurant] do |f| %>