Strange Routing error in rails 3.2 - ruby-on-rails

I am implementing an application in which i want to change the settings of the application.
While doing so I am getting an error
no routes matches {:action=>"show", :controller=>"settings", format=>"nil"}
while clicking on the open new settings tab.
my index.html is as follows:-
<h1>Listing settings</h1>
<table class="table table-striped table-bordered">
<tr>
<th>ID</th>
<th>Name</th>
<th>Value</th>
<th>Description</th>
<th>Edit</th>
<th>Delete</th>
</tr>
<% #settings.each do |c| %>
<tr>
<td><%= c.id %> </td>
<td><%= c.name %> </td>
<td><%= c.value %> </td>
<td><%= c.description %> </td>
<td><%= link_to 'Edit', {:action => 'edit', :id => c.id} %> </td>
<td><%= link_to 'Delete', {:action => 'delete', :id => c.id},
:data => { :confirm => "Are you sure you want to delete this value?" } %></td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'New Setting', {:action => 'new'} %>
My settings controller is as follows:-
class SettingsController < ApplicationController
# GET /setting
# GET /setting.json
def index
#settings = Setting.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #settings }
end
end
# GET /setting/1
# GET /setting/1.json
def show
#setting = Setting.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #setting }
end
end
# GET /setting/new
# GET /setting/new.json
def new
#setting = Setting.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #setting }
end
end
# GET /setting/1/edit
def edit
#setting = Setting.find(params[:id])
end
# POST /setting
# POST /setting.json
def create
#setting = Setting.new(params[:setting])
respond_to do |format|
if #setting.save
format.html { redirect_to #setting, notice: 'Setting was successfully created.' }
format.json { render json: #setting, status: :created, location: #setting }
else
format.html { render action: "new" }
format.json { render json: #setting.errors, status: :unprocessable_entity }
end
end
end
# PUT /setting/1
# PUT /setting/1.json
def update
#setting = Setting.find(params[:id])
respond_to do |format|
if #setting.update_attributes(params[:setting])
format.html { redirect_to #setting, notice: 'Setting was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #setting.errors, status: :unprocessable_entity }
end
end
end
# DELETE /setting/1
# DELETE /setting/1.json
def delete
#setting = Setting.find(params[:id])
#setting.deleted = 1
#setting.save
respond_to do |format|
format.html { redirect_to settings_url }
format.json { render :json => { :success => true } }
end
end
end
My new.html is as follows:-
<h1>New settings</h1>
<%= form_for #setting do |f| %>
<% if #setting.errors.any? %>
<div id="errorExplanation">
<h2><%= pluralize(#setting.errors.count, "error") %> prohibited this setting from being saved:</h2>
<ul>
<% #setting.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
Id: <%= f.text_field :id %><br>
Name: <%= f.text_field :name %><br>
Values: <%= f.text_field :value %><br>
Description: <%= f.text_field :description %><br>
<% end %>
<%= link_to 'Back', settings_path %>
My routes.rb is as follows:-
Lms::Application.routes.draw do
resources :books do
member do
post 'add'
post 'remove'
end
collection do
get 'add'
get 'list' => "books#index"
post 'get_books'
get 'get_books'
end
end
resources :books
resources :book_transactions
resources :book_issues
resources :book_holds
resources :categories
resources :users
resources :admins
resources :library_locations
resources :lov_values
resources :loan_fines
resources :lov_names
resources :loans_fines do
member do
post 'add'
post 'remove'
end
collection do
get 'add'
get 'list'
post 'get_loans_fines'
get 'get_loans_fines'
end
end
resources :settings do
member do
post 'add'
post 'remove'
end
collection do
get 'add'
get 'list'
post 'get_settings'
get 'get_settings'
end
end
root :to => 'books#index'
match ':controller(/:action(/:id))(.:format)'
The strange part is that when i click on new action it is going/redirecting to the show action..I am a bit confused why this is happening..
Can some one help me with this..

To check your routes you can run
rake routes
to inspect if you have the routes defined correctly. Also I would suggest to use
<%= link_to "New Setting", new_setting_pah %>
For your routes definition you are not defining the routes for other methods than add or remove.
I advise you to read this great tutorial on rails routes

Related

Displaying dynamic content using javascript and Rails partials

I have a list of movie categories displayed on my home page. Along with this, I have displayed the list of ALL the movies currently available in the db. When the user clicks on one of the categories, I would like to re-render the containing the list of ALL movies to show ONLY the list of movies that belong to the category that the user selected.
I use link_to to display the list of categories. The link_to would be routed to a controller function which loads the movies that belong Only to the category selected by the user. Then a js.erb would be invoked with this generated list which would in-turn invoke a Rails partial.
The Rails partial would re-render the complete movie list to display ONLY the movies that belong to the selected category. The javascript and partial are getting invoked all right but the partial fails to re-render the list. Am not sure what I'm missing here.
app/views/movies/index.html.erb
<% #categories.each do |category| %>
<tr><td>
<%= link_to category, show_category_url(:genre => category), :remote => true %> <%end%>
<%if false %>
<%= link_to show_category_url, :remote => true do %>
category
<%end %>
</td></tr>
<% end %>
<div id="#movies_list">
<% #movies.each do |movie| %>
<tr>
<td><%= movie.title %></td>
<td><%= movie.category %> </td>
<td><%= movie.rating %></td>
<% if !current_user.nil? %>
<% if movie.user.email == current_user.email %>
<td><%= link_to 'Show', movie, :class => "btn btn-primary"%></td>
<td><%= link_to 'Edit', edit_movie_path(movie), :class => "btn btn-primary" %></td>
<td><%= link_to 'Destroy', movie, method: :delete, data: { confirm: 'Are you sure?' }, :class => "btn btn-primary" %></td>
<% end %>
<% end %>
</tr>
<% end %>
</div>
app/views/movies/show.js.erb
$("#movies_list").html("<%= escape_javascript(render("show_category")) %>");
app/views/movies/_show_categories.html.erb
<% #movies_in_category.each do |movie| %>
<tr>
<td><%= movie.title %></td>
<td><%= movie.rating %></td>
<% puts "************** movies/show_category"%>
<% puts movie.title %>
<% if false %>
<td>
<%= form_for #rating do |rating_form| %>
<%= rating_form.number_field :rating, class: 'rating', 'data-size' => 'xs'%>
<%= rating_form.submit 'Add', class: 'btn btn-primary btn-success' %>
<% end %>
</td>
<% end %>
<% if !current_user.nil? %>
<% if movie.user.email == current_user.email %>
<td><%= link_to 'Show', movie, :class => "btn btn-primary"%></td>
<td><%= link_to 'Edit', edit_movie_path(movie), :class => "btn btn-primary" %></td>
<td><%= link_to 'Destroy', movie, method: :delete, data: { confirm: 'Are you sure?' }, :class => "btn btn-primary" %></td>
<% end %>
<% end %>
</tr>
<% end%>
My partial is getting invoked all right but the re-rendering of div movies_list does not happen.
This is my controller code:
class MoviesController < ApplicationController
before_action :set_movie, only: [:show, :edit, :update, :destroy]
#before_action :authenticate_user!
# GET /movies
# GET /movies.json
def index
#movies = Movie.all
$all_movies = #movies
#categories = #movies.uniq.pluck(:category)
#movies_by_category = Hash.new
#categories.each do |category|
#movies_by_category[category] = Movie.where(:category => category).length
end
end
# GET /movies/1
# GET /movies/1.json
def show
respond_to do |format|
format.js {render layout: false}
puts "############## moviescontroller/show_category"
end
end
# GET /movies/new
def new
#movie = current_user.movies.new
end
# GET /movies/1/edit
def edit
end
# POST /movies
# POST /movies.json
def create
#movie = current_user.movies.new(movie_params)
respond_to do |format|
if #movie.save
format.html { redirect_to #movie, notice: 'Movie was successfully created.' }
format.json { render :show, status: :created, location: #movie }
else
format.html { render :new }
format.json { render json: #movie.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /movies/1
# PATCH/PUT /movies/1.json
def update
respond_to do |format|
if #movie.update(movie_params)
format.html { redirect_to #movie, notice: 'Movie was successfully updated.' }
format.json { render :show, status: :ok, location: #movie }
else
format.html { render :edit }
format.json { render json: #movie.errors, status: :unprocessable_entity }
end
end
end
# DELETE /movies/1
# DELETE /movies/1.json
def destroy
#movie.destroy
respond_to do |format|
format.html { redirect_to movies_url, notice: 'Movie was successfully destroyed.' }
format.json { head :no_content }
end
end
def show_category
category_selected = params[:genre]
#all_movies = Movie.all
#movies_in_category = Movie.where(category: category_selected)
puts "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
puts category_selected
puts #movies_in_category.length
end
def login
end
private
# Use callbacks to share common setup or constraints between actions.
def set_movie
#movie = Movie.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def movie_params
params.require(:movie).permit(:title, :category, :rating)
end
end
The reason is,
<div id="#movies_list">
contents goes here..
</div>
You shouldn't add # when defining id attribute for an element, That will be used when selecting an HTML element based on the selector. So remove #
<div id="movies_list">
contents goes here..
</div>

How to show nested database

Hello I have a nested database "processing" which belongst to "shopping_process". However I want somehow to see the messages, which are saved in processing. How can I do that? If I go to http://localhost:3000/processings/index the Error: Couldn't find Processing with 'id'=index appears. Has somebody an idea?
processings_controller.rb
class ProcessingsController < ApplicationController
before_action :set_processing, only: [:show, :edit, :update, :destroy]
# GET /processings
# GET /processings.json
def index
#processings = Processing.all
end
# GET /processings/1
# GET /processings/1.json
def show
end
# GET /processings/new
def new
#processing = Processing.new
end
# GET /processings/1/edit
def edit
end
# POST /processings
# POST /processings.json
def create
#processing = Processing.new(processing_params)
respond_to do |format|
if #processing.save
format.html { redirect_to #processing, notice: 'Processing was successfully created.' }
format.json { render :show, status: :created, location: #processing }
else
format.html { render :new }
format.json { render json: #processing.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /processings/1
# PATCH/PUT /processings/1.json
def update
respond_to do |format|
if #processing.update(processing_params)
format.html { redirect_to #processing, notice: 'Processing was successfully updated.' }
format.json { render :show, status: :ok, location: #processing }
else
format.html { render :edit }
format.json { render json: #processing.errors, status: :unprocessable_entity }
end
end
end
# DELETE /processings/1
# DELETE /processings/1.json
def destroy
#processing.destroy
respond_to do |format|
format.html { redirect_to processings_url, notice: 'Processing was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_processing
#processing = Processing.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def processing_params
params.require(:processing).permit(:shopping_process_id, :shopping_list_id, :accepted, :responded, :message)
end
end
view/processings/index.html.erb
<p id="notice"><%= notice %></p>
<h1>Processings</h1>
<table>
<thead>
<tr>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #Processing.all.each do |processing| %>
<tr>
<td><%= link_to 'Show', processing %></td>
<td><%= link_to 'Edit', edit_processing_path(processing) %></td>
<td><%= link_to 'Destroy', processing, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Processing', new_processing_path %>
models/processing.rb
class Processing < ApplicationRecord
# db associations
belongs_to :shopping_process
belongs_to :shopping_list
# validations
validates :shopping_list, :presence => true
end
Now here comes the code for the database "shopping_processes"
shopping_processes_controller.rb
class ShoppingProcessesController < ApplicationController
load_and_authorize_resource
layout 'shopping_process', only: [:shopper_show, :senior_show]
# GET /shopping_processes/1
# GET /shopping_processes/1.json
def show
end
# POST /shopping_processes
# POST /shopping_processes.json
def create
#shopping_process.status =nil
#shopping_process.processed = nil
puts params.inspect
respond_to do |format|
if #shopping_process.save
format.html { redirect_to #shopping_process, notice: 'Shopping process was successfully created.' }
format.json { render :show, status: :created, location: #shopping_process }
else
format.html { render :new }
format.json { render json: #shopping_process.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /shopping_processes/1
# PATCH/PUT /shopping_processes/1.json
def update
respond_to do |format|
if #shopping_process.update(shopping_process_params)
format.html { redirect_to #shopping_process, notice: 'Shopping process was successfully updated.' }
format.json { render :show, status: :ok, location: #shopping_process }
else
format.html { render :edit }
format.json { render json: #shopping_process.errors, status: :unprocessable_entity }
end
end
end
# DELETE /shopping_processes/1
# DELETE /shopping_processes/1.json
def destroy
#shopping_process.destroy
respond_to do |format|
format.html { redirect_to shopping_processes_url, notice: 'Shopping process was successfully destroyed.' }
format.json { head :no_content }
end
end
def shopper_show
#shopping_process = ShoppingProcess.find(params[:id])
#users = {}
first = true
#shopping_process.shopping_lists.each do |shopping_list|
user = shopping_list.user
#users[user.id] = {color: (first ? 'blue' : 'yellow'), name: user.firstname + ' ' + user.lastname}
first = false
end
end
def senior_show
#shopping_process = ShoppingProcess.find(params[:id])
#shopping_process.shopping_lists.each do |shopping_list|
#if shopping_list.user == current_user
# #shopping_list = shopping_list
#end
#shopping_list = shopping_list
#to show the correct shopping list uncomment the block above and remove the declartion underneath it
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_shopping_process
#shopping_process = ShoppingProcess.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def shopping_process_params
params.require(:shopping_process).permit(:user_id, :status, :appointed, :processed, :shopping_list_id, processings_attributes: [ :shopping_list_id, :message ])
end
end
views/shopping_processes/form.html.erb
<%= form_for(shopping_process) do |f| %>
<% if shopping_process.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(shopping_process.errors.count, "error") %> prohibited this shopping_process from being saved:</h2>
<ul>
<% shopping_process.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :appointed %>
<%= f.datetime_select :appointed %>
</div>
<div class="field">
<%= f.label :shopper %>
<%= f.text_field :user_id, value: current_user.id, :readonly => true%>
</div>
<div class="field">
<%= f.label :shopping_list_id %>
<%= f.select :shopping_list_id, ShoppingList.accessible_by(current_ability).map{ |sl| [sl.name, sl.id] } %>
</div>
<!-- SUB FORM FOR NESTED RESOURCE : PROCESSINGS -->
<%= f.fields_for :processings, #shopping_process.processings.build do |ff| %>
<div>
<%= ff.label :Begleiter %>
<%= ff.select :shopping_list_id, ShoppingList.all.map{ |sl| [sl.user.firstname, sl.id]} , {:prompt => true} %>
</div>
<div>
<%= ff.label :message %>
<%= ff.text_field :message%>
</div>
<% end %>
<!-- Submit-->
<div class="actions">
<%= f.submit %>
</div>
<% end %>

Rails routing error: No route matches [DELETE]

I'm a ruby on rails noob having some trouble deleting a resource with a form_for.
I'm trying to create a wish-list for products where users can add multiple instances of the same product to their list. Rather than create a unique data-base entry for each product on the list (regardless of whether the same product is already on the list), I've included a counter column, 'row,' which increases as the user adds multiples of the same product to his or her wish list. By the same logic, I want the delete action to first decrease this counter until it reaches 0, and then remove the item from the data-base.
Here's what I've got:
The error message:
No route matches [DELETE] "/wish"
Routes
Routes match in priority from top to bottom
wishes_path GET /wishes(.:format) wishes#index
POST /wishes(.:format) wishes#create
new_wish_path GET /wishes/new(.:format) wishes#new
edit_wish_path GET /wishes/:id/edit(.:format) wishes#edit
wish_path GET /wishes/:id(.:format) wishes#show
PATCH /wishes/:id(.:format) wishes#update
PUT /wishes/:id(.:format) wishes#update
DELETE /wishes/:id(.:format) wishes#destroy
wishes/index.html.erb
<div class="wishes_body">
<h2>Your Wish-List</h2>
<table>
<thead>
<tr>
<th class="field-label col-md-2 active">
<label>Name</label>
</th>
<th class="col-md-3">Description</th>
<th class="col-md-1">Amount</th>
<th class="col-md-1">Number</th>
<th class="col-md-2">Total</th>
<th colspan="3" class="col-md-3">Remove</th>
</tr>
</thead>
<tbody>
<% #wishes.all.each do |w| %>
<%= render partial: 'wish', object: w %>
<% end %>
</tbody>
</table>
</div>
_wish.html.erb
<tr>
<td class="field-label col-md-2 active">
<label><%= wish.product.name %></label>
</td>
<td class="col-md-3"><%= wish.product.description %></td>
<td class="col-md-1"><%= '%.2f' % (wish.product.amount/100.00) %></td>
<td class="col-md-1"><%= wish.total %></td>
<td class="col-md-2"><%= '%.2f' % ((wish.product.amount/100.00) * wish.total) %></td>
<%= form for(wish_path(wish), :html => { method: 'delete' }) do %>
<td><%= f.label(:i, "How many:") %></td>
<td><%= f.number_field(:i) %></td>
<td><%= f.submit :value => "Remove" %></td>
<% end %>
</tr>
controllers/wishes.controller.rb
class WishesController < ApplicationController
def index
#wishes = Wish.where("user_id = ?", "#{current_user.id}")
end
def show
#user = current_user
#products = #user.wish_list.products.order("created_at DESC")
end
def create
#product = Product.find(params[:product_id])
if Wish.where(user_id: "#{current_user.id}", product_id: "#{#product.id}").exists?
#wish = Wish.where(user_id: "#{current_user.id}", product_id: "#{#product.id}").first
#wish.total += 1
else
#wish = #product.wishes.new
#wish.user = current_user
#wish.total = 1
end
respond_to do |format|
if #wish.save
format.html { redirect_to action: "index", notice: 'You have added <%= #wish.product %> to your wish list.' }
format.json { render :index, status: :created }
else
format.html { redirect_to #product, alert: 'Wish was not created succesfully.' }
format.json { render json: #wish.errors, status: :unprocessable_entity }
end
end
end
def destroy
case i = params[:i]
when #wish.total > i
#wish.total -= i
respond_to do |format|
format.html { redirect_to action: 'index', notice: 'You removed the item from your wish-list.' }
format.json { head :no_content }
end
when #wish.total == i
#wish.destroy
respond_to do |format|
format.html { redirect_to action: 'index', notice: 'You removed the item from your wish-list.' }
format.json { head :no_content }
end
else
format.html { redirect_to action: 'index', alert: 'You cannot remove more items than you have on your list.' }
format.json { head :no_content }
end
end
end
config.routes.rb
Rails.application.routes.draw do
root 'static_pages#index'
get 'static_pages/about'
get 'static_pages/contact'
get 'static_pages/landing_page'
post 'static_pages/thank_you'
resources :orders, only: [:index, :show, :new, :create]
resources :users
devise_for :users, :controllers => { :registrations => "my_devise/registrations" },
:path => '', :path_names => {:sign_in => 'login', :sign_out => 'logout', :sign_up => 'register'}
resources :wishes
resources :products do
resources :comments
end
resources :payments
end
You should implement this using form_tag instead of form_for, because you're not going to use #wish resource in your form:
<%= form_tag wish_url(wish), method: :delete do %>
etc.

Simple form for submit button doesn't do anything

I have this code below which loads the patient data and with each one the update button updates it but on clicking nothing happens, here is the code:
<% emergency_case.patients.each do |patient| %>
<tr>
<%= simple_form_for (:patient),url: patients_edit_path(patient.id) do |f|%>
<td><%=f.input :name ,:input_html => { :value => patient.name},label: false %></td>
<td><%=f.input :IDNumber ,:input_html => { :value => patient.IDNumber},label: false %></td>
<td><%=f.input :age ,:input_html => { :value => patient.age},label: false %></td>
<td><%=f.input :phone ,:input_html => { :value => patient.phone},label: false %></td>
<td><%=f.input :address ,:input_html => { :value => patient.address},label: false %></td>
<td><%=f.input :injury ,:input_html => { :value => patient.injury},label: false %></td>
<td><%= f.collection_select(:state_id, State.all, :id, :state) %></td>
<td><%= f.collection_select(:Act, Act.all, :id, :act) %></td>
<td><%=f.submit %></td>
<% end %>
</tr>
<% end %>
Here is the paitent controller which am sending the form for to make updates on the paitent that is sent:
class PatientsController < ApplicationController
before_action :set_patient, only: [:show, :edit, :update, :destroy]
# GET /patients
# GET /patients.json
def index
#patients = Patient.all
end
# GET /patients/1
# GET /patients/1.json
def show
end
# GET /patients/new
def new
#patient = Patient.new
end
# GET /patients/1/edit
def edit
#patient =Patient.find(params[:id])
end
# POST /patients
# POST /patients.json
def create
#patient = Patient.new(patient_params)
respond_to do |format|
if #patient.save
format.html { redirect_to #patient, notice: 'Patient was successfully created.' }
format.json { render :show, status: :created, location: #patient }
else
format.html { render :new }
format.json { render json: #patient.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /patients/1
# PATCH/PUT /patients/1.json
def update
respond_to do |format|
if #patient.update(patient_params)
format.html { redirect_to #patient, notice: 'Patient was successfully updated.' }
format.json { render :show, status: :ok, location: #patient }
else
format.html { render :edit }
format.json { render json: #patient.errors, status: :unprocessable_entity }
end
end
end
# DELETE /patients/1
# DELETE /patients/1.json
def destroy
#patient.destroy
respond_to do |format|
format.html { redirect_to patients_url, notice: 'Patient was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_patient
#patient = Patient.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def patient_params
params.require(:patient).permit(:name, :isDead, :status, :IDNumber, :emergency_case_id,:state_id,:address,:age,:phone,:injury,:act)
end
end
Several issues to contend with here:
<% emergency_case.patients.each do |patient| %>
<%= content_tag :tr do %>
<%= simple_form_for patient, method: :put do |f|%>
<% attributes = %i(name IDNumber age phone address injury) %>
<% patient.attributes do |attr| %>
<%= content_tag :td, f.input attr, input_html: { value: patient.send(attr)}, label: false %>
<% end %>
<%= content_tag :td, f.state_select :state_id %>
<%= content_tag :td, f.collection_select(:Act, Act.all, :id, :act) %>
<%= content_tag :td, f.submit %>
<% end %>
<% end %>
<% end %>
ALWAYS use snake_case for attributes (IDNumber is baaad umkay)
Check out the state_select gem
Loops are the BEST way to keep forms succinct & efficient
Your form is sending to the edit action -- you need to send to the update action
#4 will answer your question -- patients_edit_path(patient.id)
What you need is to send to the update path: patient_path(patient), method: :put... or simply: patient, method: :put
let simple form do the work for you on the url, method, etc unless you have something that is custom. If this doesn't work please post more info on the error you are getting in your post.
<% emergency_case.patients.each do |patient| %>
<tr>
<%= simple_form_for patient do |f|%>
....#form stuff
<td><%=f.submit %></td>
<% end %>
</tr>
<% end %>

Association between Post and Location

This my first ruby on rails application.
Model Location and Post, Location has many post.I create location as tree structure with ancestry gem.
class Post < ActiveRecord::Base
belongs_to :location, :counter_cache => true
end
class Location < ActiveRecord::Base
include Tree
has_ancestry :cache_depth => true
has_many :posts
end
This my Post Controller
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
def index
#posts = Post.all
end
def show
end
def new
#post = Post.new
end
def edit
end
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 action: 'show', status: :created, location: #post }
else
format.html { render action: 'new' }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #post.update(post_params)
format.html { redirect_to #post, notice: 'Post was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
def destroy
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url }
format.json { head :no_content }
end
end
private
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, :location_id)
end
end
Creating Post with location in Post _form.html.erb
<%= simple_form_for #post do |f| %>
<% if #post.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#post.errors.count, "error") %> prohibited this post from being saved: </h2>
<ul>
<% #post.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.input :name %>
<%= f.select :location_id, Location.all.at_depth(4) { |l| [ l.name, l.id ] } %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
My question are
First question- f.select :location_id , how display location name, not location id, i am using with simple form
Second question- Post index got error in <%= post.location.name %>
<% #posts.each do |post| %>
<tr>
<td><%= post.name %></td>
<td><%= post.location.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 %>
First question:
Check the simple_form syntax for a dropdown. It is mentioned in the docs and you should be able to get this working by yourself.
Second question:
Does the offending post really have a related location? If it does not have one, it can not display the name of course. To counter these nil errors, use try:
<%= post.location.try(:name) %>
try will call the method name on location only if location is not nil.
For your first question :
Maybe you should read about "options_for_select"
http://guides.rubyonrails.org/form_helpers.html#option-tags-from-a-collection-of-arbitrary-objects
<% cities_array = City.all.map { |city| [city.name, city.id] } %>
<%= options_for_select(cities_array) %>
For your second question:
What is your error ?
Maybe one of your "post.location" is nil.
If so, try:
post.location.name unless post.location.nil?
Hope this can help

Resources