Routing error in Rails embedded form - ruby-on-rails

I have embedded a rails form as a simple dropdown menu in an html table. I have also implemented the form in such a way that whenever there is a change in the drop down menu then the form is submitted. But I am getting a routing error which I am trying to resolve.
The form code:
<td>
<%= form_for(lead, :action => 'update_lead_status', :html => {:id => 'lead_form'}, :remote => true) do |f| %>
<%= f.select(:status, ["to_call","called","confirmed","lite"], {:selected => lead.status}, :onchange => "$('#lead_form').submit();") %>
<% end %>
</td>
The routes.rb file:
get 'leads/:id/edit_lead_status' => "leads#edit_lead_status"
put 'leads/:id/update_lead_status'=> "leads#update_lead_status"
The leads_controller.rb file:
#PUT
def update_lead_status
#lead = Lead.find(params[:id])
respond_to do |format|
format.js
if #lead.update_attributes(params[:lead])
format.html { redirect_to leads_url, notice: 'Lead was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #lead.errors, status: :unprocessable_entity }
end
end
end
Also my embedded form in the table is at the /leads URL where I try to redirect on successful update.
The logs from my server:
ActionController::RoutingError (No route matches [PUT] "/leads/130"):
status is an accessible attribute in my leads model.
Please let me know where I am going wrong?
UPDATE:
So I tried sevenseacat's answer and it called my update_lead_status but with a wrong parameter. My table is like this:
<% #leads.each do |lead| %>
<tr>
<td><%= lead.id %></td>
<td><%= lead.prefix %></td>
<td><%= lead.name %></td>
<td><%= lead.mobile %></td>
<td><%= lead.phone %></td>
<td><%= lead.category %></td>
<td><%= lead.area %></td>
<td><%= lead.city %></td>
<td><%= lead.updated_at %></td>
<td><%= lead.is_valid %></td>
<td><%= lead.vendor_status %></td>
<td><%= lead.call_tries %></td>
<td>
<%= form_for(lead, url: update_lead_status_path(lead.id), :html => {:id => 'lead_form'}, :remote => true) do |f| %>
<%= f.select(:status, ["to_call","called","confirmed","lite"], {:selected => lead.status}, :onchange => "$('#lead_form').submit();") %>
<% end %>
</td>
<td><%= lead.remarks %><%= link_to lead.remarks, :controller => "leads", :action => "edit_lead_remarks", :id => lead, :remote => true %>
</td>
</tr>
<% end %>
Here for every row in the table it takes id as the id of the first lead in the table.

You're not specifying the action URL for the form properly - it should be for example form_for(lead, url: update_lead_status_path(lead))
(assuming you have named your route in your routes.rb, eg, as: :update_lead_status).

Try after adding following line of code in your routes.rb file.
resources :leads

Related

Create multiple entries with checkbox and strong params in Rails4

I am having problems with the following scenario:
My users do searches by keywords which produces a list. The user has 2 actions either add them to a favorites table or block them using check boxes.
The problem I have is that when users click "Add to Favorites" the form passes a list of hashes to my strong params method and I am not able to pass it correctly.
I think the problem is that the hash required by strong_params is inside another hash.
Also I have no idea on how to pass the same hash to the BlockController when user click "Block"
This is the error message:
param is missing or the value is empty: {:favorites=>{:name=>"Jon Doe", :title=>"Provider", :company=>"Acme", :location=>"Dubai", :profile=>"Group A", :notes=>""}}
My results.html.erb is
<table class="table table-striped table-bordered">
<tr>
<th class="center">Name</th>
<th class="center">Title</th>
<th class="center">Company</th>
<th class="center">Location</th>
<th class="center">Profile</th>
<th class="center">Select</th>
</tr>
<%= form_tag favorites_path do %>
<%= #results.length %>
<% #results.each do |key,value| %>
<tr>
<td><%= value['name'] %></td>
<td><%= value['title'] %></td>
<td><%= value['company'] %></td>
<td><%= value['location'] %></td>
<td><%= link_to 'Profile', value['profile'],:target => "_blank"%></td>
<td><%=check_box_tag 'favorite[]', {:name => value['name'],:title =>value['title'],:company => value['company'],:location => value['location'], :profile=> value['profile'], :notes =>""}%></td>
</tr>
<% end %>
<%= submit_tag "Add to Favorites", name: 'add', class: 'btn btn-primary' %>
<%= submit_tag "Block Profiles", name: 'block', class: 'btn btn-danger' %>
<% end %>
</table>
this is how my strong_params method looks:
def favorite_params
params[:profiles].each do |e|
params.require(e).permit(:name, :title, :company, :location, :profile, :notes)
end
end
Any ideas?
Update:
I am able to pass params as:
def favorite_params
params.permit(:commit,favorite:[])
end
create method:
def create
#favorite = Favorite.new(favorite_params)
#favorite.user_id = current_user.id
respond_to do |format|
if #favorite.save
format.html { redirect_to #favorite, notice: 'Favorite was successfully created.' }
format.json { render :show, status: :created, location: #favorite }
format.js { render :show, status: :created, location: #favorite }
else
format.html { render :new }
format.json { render json: #favorite.errors, status: :unprocessable_entity }
end
end
end
Reference to http://api.rubyonrails.org/classes/ActionController/Parameters.html
Don't use each, use permit or require directly
Try this:
params.permit(profiles: {favorites: [:name, :title, :company, :location, :profile, :notes]})
#or :
params.permit(profiles: [{favorites: [:name, :title, :company, :location, :profile, :notes]}])
#=>{:profiles=>{:favorites=>{:name=>"Jon Doe", :title=>"Provider", :company=>"Acme", :location=>"Dubai", :profile=>"Group A", :notes=>""}}}
or :
params.require(:profiles).permit( favorites: [:name, :title, :company, :location, :profile, :notes])
#=>{:favorites=>{:name=>"Jon Doe", :title=>"Provider", :company=>"Acme", :location=>"Dubai", :profile=>"Group A", :notes=>""}}
UPDATE
According to OP's modification of the view, the favorite_params should be:
params.require(:favorite)
Then in the create action use each to create every member of the array, becase check_box pass string as value, we have to eval the string into hash again.
favorite_params.each do |fp|
f=Favorite.new(eval(fp))
f.user_id = current_user.id
f.save
end
But use eval to transfer the params is not safe. I suggest you to modify your view to:
<%= form_tag favorites_path do %>
<%= #results.length %>
<% #results.each do |key,value| %>
<tr>
<td><%= value['name'] %></td>
<td><%= value['title'] %></td>
<td><%= value['company'] %></td>
<td><%= value['location'] %></td>
<td><%= link_to 'Profile', value['profile'],:target => "_blank"%></td>
<td><%= check_box_tag "favorites[#{value['name']}][checked]", 'checked',true %>
<%= hidden_field_tag "favorites[#{value['name']}][name]" , value['name'] %>
<%= hidden_field_tag "favorites[#{value['name']}][title]" , value['title'] %>
<%= hidden_field_tag "favorites[#{value['name']}][company]" , value['company'] %>
<%= hidden_field_tag "favorites[#{value['name']}][location]" , value['location'] %>
<%= hidden_field_tag "favorites[#{value['name']}][profile]" , value['profile'] %>
<%= hidden_field_tag "favorites[#{value['name']}][note]" , "" %>
</td>
</tr>
<% end %>
<%= submit_tag "Add to Favorites", name: 'add', class: 'btn btn-primary' %>
<%= submit_tag "Block Profiles", name: 'block', class: 'btn btn-danger' %>
<% end %>
From this view, you may have params like this:
{:favorites=>{
"Jon Doe" => {:checked => "checked", :name=>"Jon Doe", :title=>"Provider", :company=>"Acme", :location=>"Dubai", :profile=>"Group A", :notes=>""},
"Alberto" => {:name=>"Alberto", :title=>"DS", :company=>"Dufrain", :location=>"chester", :profile=>"", :notes=>""}
}
}
Then change your favorite_params to :
params.require(:favorites).select{|k,v| v[:checked]}.map{|k,v| v.except(:checked)}
Use select to get all checked members, and except the checked hash key that generated by check_box,so you could get an array of hashes like:
[{"name"=>"Jon Doe", "title"=>"Provider", "company"=>"Acme", "location"=>"Dubai", "profile"=>"Group A", "notes"=>""}]
Then you could use favorite_params safely without eval.
But on my point, your requiement is so similar as Mark V's question. So you can study using accepts_nested_attributes_for to simplify your code.
i am on the way home so have to use my phone to type a new answer. my spell may wrong.
as you see in your console. you should get the favorites array use require only.
params.require(:favorite)
then in your create action use each to create every member of the array.
favorite_params.each do |fp|
f=Favorite.new(fp)
f.user_id =
f.save
end

Rails and SQLITE: Images are not being displayed

I am very new to Rails and Web-programming and hope you can help me out with my very first project.
I am developing a website for a Real Estate Agency.
I have 3 tables in my database (Homes: Home_ID, Home_Name, Admin_ID; Admins: Admin_ID, Admin_Name, Admin_Email; Images: Image_ID, Image_Path, Image_Name, Home_ID, Admin_ID).
All 3 tables have been created using scaffold. The image information (name, path, image_id, home_id etc) have been entered in SQLite.
I get all text information of the different houses displayed correctly on the website except the pictures.
My attempt to link it in the view/home/index.html.erb created the following error:
undefined method `image_path' for #<Home:0xb63d85e0>
I used below code:
<% #homes.each do |home| %>
<tr>
<td><%= home.name %></td>
<td><%= home.details %></td>
<td><%= home.region %></td>
<td><%= home.address %></td>
<td><%= home.price %></td>
<td><%= home.admin_id %></td>
<td><%= home.image_path %></td>
</tr>
<% end %>
</table>
It looks like that the data entered in SQLite do not sync with rails.
Do you have any idea what I have done wrong and how I can fix it?
Thank you.
I'm not positive what the relationship would be between your images and home models would be so correct me if I'm wrong, but I'm guessing that homes will have many images. Each image would belong to one home. Is this correct? If so, you will need to declare that in your models like so:
models/home.rb
has_many :images
models/image.rb
belongs_to :home
You will then need to add this to the image database:
t.integer "home_id"
You can add it by going to the command line and typing:
rails g migration AddHomeToImages home_id:integer
You should look in db/migrate/ and then the most recent migration file and make sure it looks like this:
add_column :images, :home_id, :integer
Then run:
rake db:migrate
At this point you'll only need to update your controller and views to show this association. Let me know if this helps and if so I'll help you with your controller and views.
What's happening is that you are looping through a selection of records from the Home table. Because of this, when you call
<td><%= home.image_path %></td>
it's not recognizing the attribute image_path because you don't have image_path as a column of Home table. You only have Home_ID, Home_Name, Admin_ID for your columns. You will have to look into associations between models in order to figure out how to grab the image_path for each home record. You can start here.
If you update the code later on I'll be glad to comment on it.
I think that the best solution here will be to use paperclip gem.
You can take a look at this very old railscast eoisode just to understand how it works:
http://railscasts.com/episodes/134-paperclip
And here is github repository:
https://github.com/thoughtbot/paperclip
Paperclip will help you with paths, styles and preview for your images.
Thanks Jason,
I agree that it is a bit big for newbies, but the requirements were that we do a website where we need to read and write from/to a database. We had a quick introduction to rails with partnerwork and are now on our own and a "bit" lost and running out of time.
Here is the error message I am getting:
NameError in Homes#index
undefined local variable or method `image' for
<#:0xb62f7aa4>
Extracted source (around line #20):
17: <% #homes.each do |home| %>
18: <tr>
19: <td><%= home.name %></td>
20: <td><%= image.home_id %></td>
21: <td><%= home.details %></td>
22: <td><%= home.region %></td>
23: <td><%= home.address %></td>
When I create the database tables I had an Image_ID in the homes table, but I was told that I don`t need it and that it is enough to have only Home_ID in the images table.
I understand that the error is caused because of image.home_id.
What is your opinion? Should I add the Image_ID back to the homes table in order to display all images for the respective home_id or is there another way? I would like to be able to decide which picture will be displayed as the main picture and which ones as the smaller pictures.
Here is the code I use:
models/home.rb
class Home < ActiveRecord::Base
attr_accessible :address, :admin_id, :details, :name, :price, :region
has_many :images
end
models/image.rb
class Image < ActiveRecord::Base
attr_accessible :image_description, :image_name, :image_path
belongs_to :home
end
views/homes/index.html.erb
<h1>Listing homes</h1>
<table>
<tr>
<th>Name</th>
<th>Image</th>
<th>Details</th>
<th>Region</th>
<th>Address</th>
<th>Price</th>
<th>Admin</th>
<th></th>
<th></th>
<th></th>
</tr>
<% #homes.each do |home| %>
<tr>
<td><%= home.name %></td>
<td><%= image.home_id %></td>
<td><%= home.details %></td>
<td><%= home.region %></td>
<td><%= home.address %></td>
<td><%= home.price %></td>
<td><%= home.admin_id %></td>
<td><%= link_to 'Show', home %></td>
<td><%= link_to 'Edit', edit_home_path(home) %></td>
<td><%= link_to 'Destroy', home, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'New Home', new_home_path %>
views/homes/show.html.erb
<p id="notice"><%= notice %></p>
<p>
<b>Name:</b>
<%= #home.name %>
</p>
<p>
<b>Image:</b>
<%= #image.home_id %>
</p>
<p>
<b>Details:</b>
<%= #home.details %>
</p>
<p>
<b>Region:</b>
<%= #home.region %>
</p>
<p>
<b>Address:</b>
<%= #home.address %>
</p>
<p>
<b>Price:</b>
<%= #home.price %>
</p>
<p>
<b>Admin:</b>
<%= #home.admin_id %>
</p>
<%= link_to 'Edit', edit_home_path(#home) %> |
<%= link_to 'Back', homes_path %>
views/images/_form.html.erb
<%= form_for(#image) do |f| %>
<% if #image.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#image.errors.count, "error") %> prohibited this image from being saved:</h2>
<ul>
<% #image.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :image_name %><br />
<%= f.text_field :image_name %>
</div>
<div class="field">
<%= f.label :image_path %><br />
<%= f.text_field :image_path %>
</div>
<div class="field">
<%= f.label :image_description %><br />
<%= f.text_area :image_description %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
controllers/images_controller.rb
class ImagesController < ApplicationController
# GET /images
# GET /images.json
def index
#images = Image.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #images }
end
end
# GET /images/1
# GET /images/1.json
def show
#image = Image.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #image }
end
end
# GET /images/new
# GET /images/new.json
def new
#image = Image.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #image }
end
end
# GET /images/1/edit
def edit
#image = Image.find(params[:id])
end
# POST /images
# POST /images.json
def create
#image = Image.new(params[:image])
respond_to do |format|
if #image.save
format.html { redirect_to #image, notice: 'Image was successfully created.' }
format.json { render json: #image, status: :created, location: #image }
else
format.html { render action: "new" }
format.json { render json: #image.errors, status: :unprocessable_entity }
end
end
end
# PUT /images/1
# PUT /images/1.json
def update
#image = Image.find(params[:id])
respond_to do |format|
if #image.update_attributes(params[:image])
format.html { redirect_to #image, notice: 'Image was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #image.errors, status: :unprocessable_entity }
end
end
end
# DELETE /images/1
# DELETE /images/1.json
def destroy
#image = Image.find(params[:id])
#image.destroy
respond_to do |format|
format.html { redirect_to images_url }
format.json { head :no_content }
end
end
end
Thank you so much. I really appreciate your help!!!

How can I pass the parameters to controller correctly?

From show view: I'd like to pass the shown message's id to discard action and trash the message.
From index view: I'd like to pass the checked messages' ids to discard action and trash them all at once.
But I only can trash one record at once even if I check multiple and submit from index view.
How can I archive both 1 and 2 with the same action????
Routes
match 'messages/discard(/:id)' => 'messages#discard', :via => :post , :as => :discard_messages
index view
<%= form_tag(:action => discard, :via => 'post') do %>
<% #messages.each do |m| %>
<tr>
<td><%= check_box_tag "id",m.id %></td>
<td><%= m.last_message.id %></td>
<td><%= 'unread' if m.is_unread?(current_user) %></td>
<td><%= m.last_message.created_at.to_s(:jp) %></td>
<td><%= m.last_sender.username %></td>
<td><%= link_to m.subject, show_messages_path(:id => m, :breadcrumb => #box) %></td>
</tr>
<% end %>
<%= submit_tag "discard", :class => 'btn' %>
<% end %>
show view
<%= link_to 'Discard', discard_messages_path(#messages), :class => 'btn', :method => 'post' %>
controller
def discard
conversation = Conversation.find_all_by_id(params[:id])
if conversation
current_user.trash(conversation)
flash[:notice] = "Message sent to trash."
else
conversations = Conversation.find(params[:conversations])
conversations.each { |c| current_user.trash(c) }
flash[:notice] = "Messages sent to trash."
end
redirect_to :back
end
use the [] naming in your html, which rails will then make available as an array in the params
index.html.erb
<td><%= check_box_tag "message_id[]", m.id %></td>
controller
# ...
else
conversations = Conversation.where("id IN (?)", params[:message_id][])
# ...
to simplify things further I would remove the conditional in your action and create two separate actions
routes
resource :messages do
member do
post 'discard' # /messages/:id/discard
end
collection do
post 'discard_all' # /messages/discard_all?message_id[]=1&message_id[]=22
end
end

Rails Routing - :action => 'new' returns error "No route matches {:action=>"show"... in the same controller

I am writing the code for a model called "ExternalDatabase".
The model file has no code in it outside of the class declaration. I have added view pages for index, new, show, and _form .html.erb.
config/routes.rb contains the line resources :external_databases. The model contains no nested resources at this time. There are other models declared within this application, though none of them interact with this model at the moment and they are all tested and are functional and closed prior to declaring resources :external_databases.
I have a link from within the index view to new_external_database_path, which behaves exactly like {:action => "new", :controller => "external_database"} if I am following correctly.
This should theoretically load application/external_databases/new which will render _form.html.erb. The first line of _form is <%= form_for(#external_database) do |f| %>
The problem as stated in the post title occurs when using the link to /new. The url application/external_databases/new has the following error:
No route matches {:action=>"show", :controller=>"external_databases"}
When I created a data member using rails console, it was displayed properly by index and show. The same _form file is used by the edit method, and successfully edits the console-created data member. Destroy also functions.
...So why isn't it recognizing the new method?
My controller code for this model:
class ExternalDatabasesController < ApplicationController
def index
#external_databases = ExternalDatabase.all
respond_to do |format|
format.html # index.html.erb
format.json { render :json => #external_databases }
end
end
# POST /external_databases
# POST /external_databases.json
def new
#external_database = ExternalDatabase.new
respond_to do |format|
format.html # new.html.erb
format.json { render :json => #external_database }
end
end
def show
#external_database = ExternalDatabase.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json {render :json => #external_database }
end
end
def create
#external_database = ExternalDatabase.new(params[:external_database])
respond_to do |format|
if #external_database.save
format.html {redirect_to #external_database, :notice => "New External Database Profile was created successfully!"}
format.json {render :json => #external_database, :status => :created, :location => #external_database}
else
format.html {render :action => "new"}
format.json { render :json => #external_database.errors, :status => :unprocessable_entity }
end
end
end
#GET /external_databases/1/edit
def edit
#external_database = ExternalDatabase.find(params[:id])
end
# PUT /external_databases/1
# PUT /external_databases/1.json
def update
#external_database = ExternalDatabase.find(params[:id])
respond_to do |format|
if #external_database.update_attributes(params[:external_database])
format.html {redirect_to #external_database, :notice => "External Database Profile was updated successfully!" }
format.json {head :ok}
else
format.html { redner :action => "edit" }
format.json {render :json => #external_database.errors, :status => :unprocessable_entity }
end
end
end
# DELETE /external_databases/1
# DELETE /external_databases/1.json
def destroy
#external_database = ExternalDatabase.find(params[:id])
#external_database.destroy
respond_to do |format|
format.html { redirect_to external_databases_rul }
format.json { head :ok }
end
end
end
Update: Added routes.rb and Views code
My routes.rb file:
App::Application.routes.draw do
resources :type_as do
resources :type_bs
end
resources :type_bs do
resources :type_as
resources :type_cs
end
resources :type_cs do
resources :type_bs
end
resources :external_databases
root :to => "home#index"
end
Views:
external_databases_form
<%= form_for(#external_database) do |f| %>
<div class="field">
<%= f.label :name %><br/>
<%= f.text_field :name %><br/>
</div>
<div class="field">
<%= f.label :description %><br/>
<%= f.text_field :description %><br/>
</div>
<div class="field">
<%= f.label :url %><br/>
<%= f.text_field :url %><br/>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
index.html.erb
<p id="notice"><%= notice %></p>
<h1>External Databases</h1>
<table border="1">
<tr>
<th>Database Name</th>
</tr>
<% #external_databases.each do |exdb| %>
<tr>
<td><%= exdb.name %></td>
<td><%= truncate(exdb.description) %></td>
<td><%= link_to 'Show', exdb %></td>
<!-- link_to.... :target => "_blank" will open the url in a new window -->
<td><%= link_to 'Visit', exdb.url, :target => "_blank" %></td>
<td><%= link_to 'Edit', edit_external_database_path(exdb)%></td>
<td><%= link_to 'Destroy', exdb, :confirm => 'Are you sure?', :method => :delete %></td>
</tr>
<% end %>
</table>
<br/>
<%= link_to 'New External Database Profile', { :action => "new", :controller => "external_databases" }%> |
<%= link_to 'Home', root_path %>
new.html.erb
<h1>Creating a new External Database Profile</h1>
<%= render 'form' %>
<%= link_to 'Back', external_database_path %>
show.html.erb
<p id="notice"><%= notice %></p>
<table cellspacing="3" cellpadding="5" border="1">
<tr>
<th><b>External Database Name</b></th>
<th><b>Database ID</b></th>
</tr>
<tr>
<td><%= #external_database.name %></td>
<td><%= #external_database.id %></td>
</tr>
<tr colspan="2">
<th><b>URL</b></th>
</tr>
<tr colspan="2">
<td><%= #external_database.url %></td>
<td><%= link_to 'Visit External Database', #external_database.url %></td>
</tr>
</table>
<p>
<h3>Description</h3>
<!% #external_database.description.split.scan(/.{,60}/).each do |line| %>
<!%= line %><br/>
<!% end %>
</p>
<br /><br /><br />
<%= link_to 'Back to External Database Index', external_databases_path %> |
<%= link_to 'Edit', edit_external_database_path(#external_database) %> |
<%= link_to 'Destroy', :confirm => 'Are you sure?', :method => :delete %>
You have a typo in your new.html.erb file in your 'back' link. It should be:
external_databases_path
You can compare it with your own back link in show.html.erb above.
Fixed: new.html.erb
<h1>Creating a new External Database Profile</h1>
<%= render 'form' %>
<%= link_to 'Back', external_databases_path %>
I had a similar issue to this. Followed the instructions here with no luck. At the base of my form_for code for submit I had the 'create new' and 'delete' buttons. Turns out my create new was generating an error because of a dodgy delete button :/. Anyway, I can at least comment that out to get the new button working and then focus on debugging the delete button instead.
= f.submit "Submit", class: "btn btn-large btn-primary"
= link_to 'Create New', new_matrix_header_path, class: 'btn btn-primary'
-#= link_to 'Delete', matrix_header_path(#matrix_header), method: :delete, data: { confirm: 'Are you sure?'}, class: 'btn btn-danger'
I looked through the stack and found it beginning the error around line 13 of my view which was the line with my delete button.
Started GET "/matrix_headers/new" for 127.0.0.1 at 2014-10-28 21:08:48 +1000
Processing by MatrixHeadersController#new as HTML
User Load (0.2ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 ORDER BY `users`.`id` ASC LIMIT 1
Rendered shared/_error_messages.html.erb (0.4ms)
Rendered matrix_headers/_form.html.haml (21.0ms)
Rendered matrix_headers/new.html.haml within layouts/application (22.6ms)
Completed 500 Internal Server Error in 36ms
ActionController::UrlGenerationError - No route matches {:action=>"show", :controller=>"matrix_headers", :format=>nil, :id=>#<MatrixHeader id: nil>} missing required keys: [:id]:
actionpack (4.1.1) lib/action_dispatch/journey/formatter.rb:39:in `generate'
actionpack (4.1.1) lib/action_dispatch/routing/route_set.rb:597:in `generate'
actionpack (4.1.1) lib/action_dispatch/routing/route_set.rb:627:in `generate'
actionpack (4.1.1) lib/action_dispatch/routing/route_set.rb:663:in `url_for'
actionpack (4.1.1) lib/action_dispatch/routing/url_for.rb:155:in `url_for'
actionview (4.1.1) lib/action_view/routing_url_for.rb:83:in `url_for'
actionpack (4.1.1) lib/action_dispatch/routing/route_set.rb:228:in `call'
actionpack (4.1.1) lib/action_dispatch/routing/route_set.rb:179:in `call'
actionpack (4.1.1) lib/action_dispatch/routing/route_set.rb:268:in `block (2 levels) in define_url_helper'
() media/jay/DATA/rails_projects/my_app/app/views/matrix_headers/_form.html.haml:13:in `block in _app_views_matrix_headers__form_html_haml__2669648707298145379_8667520'
By commenting out the delete button it now routes through to new correctly without going to the No route matches {:action=>"show" error.

Displaying Nested Scaffolds on Index

I'm trying to display something like this on posts/index.html.erb
Post #1
Comment #1 for Post #1
Comment #2
Post #2
Comment #1 for Post #2
etc.
It works fine if I go to /posts/1/comments/, /posts/2/comments/ etc
Since it's using the index file, there is no :post_id in the URL and it throws a nil error. The models use the appropriate have_many and belongs_to.
Here's part of routes.rb
resources :posts do
resources :comments
end
resources :posts
Here's part of my posts_controller.rb
def index
#posts = Post.all
#comments = params[:post_id][:desc]
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #posts }
end
end
Here's part of index.html.erb
<% #posts.each do |post| %>
<tr>
<td><%= post.title %></td>
<td><%= link_to 'Show', post %></td>
<td><%= link_to 'Edit', edit_post_path(post) %></td>
<td><%= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete %></td>
</tr>
<tr><td><%= #comments %></td></tr>
<% end %>
</table>
Thanks!
Well, since comments belongs_to a given post, you just need to have a separate loop in the view to iterate over each of the comments for a given post.
So take the #comments var out of your controller and index view, and do this in the index view instead where you currently have #comments:
<% for comment in post.comments %>
<tr><td><%= comment.user_name %><%= comment.text %></td></tr>
<% end %>
I made the user_name and text attrs up of course you would use whatever is in your comment model.
ian.

Resources