My restaurant review app works in Localhost but when i try this on heroku and click on the link to show the reviews i get We're sorry, but something went wrong. heroku logs shows the following information with the error ActionView::Template::Error (undefined method `capitalize' for nil:NilClass):
2014-08-20T09:32:49.175203+00:00 app[web.1]: 46: <h4>
2014-08-20T09:32:49.175221+00:00 app[web.1]: 49: <p><%= review.created_at.strftime("%-m/%-d/%y") %></p>
2014-08-20T09:32:49.175223+00:00 app[web.1]: 50: </td>
2014-08-20T09:32:49.175225+00:00 app[web.1]: app/views/restaurants/show.html.erb:47:in `block in _app_views_restaurants_show_html_erb__3540437068917616550_70094864076860'
2014-08-20T09:32:49.175226+00:00 app[web.1]: app/views/restaurants/show.html.erb:43:in `_app_views_restaurants_show_html_erb__3540437068917616550_70094864076860'
2014-08-20T09:32:49.175303+00:00 app[web.1]: 48: </h4>
2014-08-20T09:32:49.175229+00:00 app[web.1]:
2014-08-20T09:32:49.175284+00:00 app[web.1]: ActionView::Template::Error (undefined method `capitalize' for nil:NilClass):
2014-08-20T09:32:49.175307+00:00 app[web.1]: app/views/restaurants/show.h
tml.erb:47:in `block in _app_views_restaurants_show_html_erb__3540437068917616550_70094864076860'
2014-08-20T09:32:49.175298+00:00 app[web.1]: 45: <td>
2014-08-20T09:32:49.175199+00:00 app[web.1]: ActionView::Template::Error (undefined method `capitalize' for nil:NilClass):
2014-08-20T09:32:49.175282+00:00 app[web.1]:
2014-08-20T09:32:49.175304+00:00 app[web.1]: 49: <p><%= review.created_at.strftime("%-m/%-d/%y") %></p>
2014-08-20T09:32:49.175309+00:00 app[web.1]: app/views/restaurants/show.html.erb:43:in `_app_views_restaurants_show_html_erb__3540437068917616550_70094864076860'
2014-08-20T09:32:49.175300+00:00 app[web.1]: 46: <h4>
2014-08-20T09:32:49.175218+00:00 app[web.1]: 47: <%= "#{review.user.first_name.capitalize} #{review.user.last_name.capitalize[0]}." %>
2014-08-20T09:32:49.175301+00:00 app[web.1]: 47: <%= "#{review.user.first_name.capitalize} #{review.user.last_name.capitalize[0]}." %>
2014-08-20T09:32:49.175310+00:00 app[web.1]:
2014-08-20T09:32:49.175305+00:00 app[web.1]: 50: </td>
2014-08-20T09:32:49.175312+00:00 app[web.1]:
2014-08-20T09:32:49.626763+00:00 heroku[router]: at=info method=GET path="/restaurants/5" host=yelpdemo2014.herokuapp.com request_id=76387447-eb34-431b-9fcf-785a901e95ee fwd="185.30.24.132" dyno=web.1 connect=1ms service=58ms status=500 bytes=1030
2014-08-20T09:32:49.580600+00:00 app[web.1]: Parameters: {"id"=>"5"}
2014-08-20T09:32:49.580595+00:00 app[web.1]: Parameters: {"id"=>"5"}
2014-08-20T09:32:49.617957+00:00 app[web.1]: Rendered restaurants/show.html.erb within layouts/application (20.7ms)
2014-08-20T09:32:49.617970+00:00 app[web.1]: Rendered restaurants/show.html.erb within layouts/application (20.7ms)
2014-08-20T09:32:49.620207+00:00 app[web.1]: Completed 500 Internal Server Error in 37ms
2014-08-20T09:32:49.622252+00:00 app[web.1]: ActionView::Template::Error (undefined method `capitalize' for nil:NilClass):
2014-08-20T09:32:49.580536+00:00 app[web.1]: Processing by RestaurantsController#show as HTML
2014-08-20T09:32:49.620214+00:00 app[web.1]: Completed 500 Internal Server Error in 37ms
2014-0
show.html
div class="row">
<div class="col-md-3">
<%= image_tag #restaurant.image_url %>
<h2>
<%= #restaurant.name %>
</h2>
<div class="star-rating" data-score= <%= #avg_rating %> ></div>
<p><%= "#{#reviews.length} reviews" %></p>
<p>
<strong>Address:</strong>
<%= #restaurant.address %>
</p>
<p>
<strong>Phone:</strong>
<%= #restaurant.phone %>
</p>
<p>
<strong>Website:</strong>
<%= link_to #restaurant.website, #restaurant.website %>
</p>
<%= link_to 'Write a review', new_restaurant_review_path(#restaurant), class: "btn btn-primary" %>
</div>
<div class="col-md-9">
<% if #reviews.blank? %>
<h3>No reviews yet, be the first to write one!</h3>
<% else %>
<table class="table">
<thead>
<tr>
<th class="col-md-3"></th>
<th class="col-md-9"></th>
</tr>
</thead>
<tbody>
<% #reviews.each do |review| %>
<tr>
<td>
<h4>
<%= "#{review.user.first_name.capitalize} #{review.user.last_name.capitalize[0]}." %>
</h4>
<p><%= review.created_at.strftime("%-m/%-d/%y") %></p>
</td>
<td>
<div class="star-rating" data-score= <%= review.rating %> ></div>
<p><%= h(review.comment).gsub(/\n/, '<br/>').html_safe %></p>
</td>
</tr>
<% end %>
</tbody>
</table>
<% end %>
</div>
</div>
<%= link_to 'Edit', edit_restaurant_path(#restaurant), class: "btn btn-link" %> |
<%= link_to 'Back', restaurants_path, class: "btn btn-link" %>
<script>
$('.star-rating').raty({
path: 'https://s3-eu-west-1.amazonaws.com/yelpdemoneil/stars',
readOnly: true,
score: function() {
return $(this).attr('data-score');
}
});
</script>
restaurant controller
class RestaurantsController < ApplicationController
before_action :set_restaurant, only: [:show, :edit, :update, :destroy]
# GET /restaurants
# GET /restaurants.json
def index
#restaurants = Restaurant.all
end
# GET /restaurants/1
# GET /restaurants/1.json
def show
#reviews = Review.where(restaurant_id: #restaurant.id).order("created_at DESC")
if #reviews.blank?
#avg_rating = 0
else
#avg_rating = #reviews.average(:rating).round(2)
end
end
# GET /restaurants/new
def 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 #restaurant, notice: 'Restaurant was successfully created.' }
format.json { render action: 'show', status: :created, location: #restaurant }
else
format.html { render action: '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 { head :no_content }
else
format.html { render action: '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 }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_restaurant
#restaurant = Restaurant.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def restaurant_params
params.require(:restaurant).permit(:name, :address, :phone, :website, :image)
end
end
Nil
The error is here:
ActionView::Template::Error (undefined method `capitalize' for nil:NilClass)
The problem is that you're calling a method on a variable / object which isn't set. As you mention it's only showing on Heroku, I'd say that it's caused by you not having the required records in your database
The fix for this is rather simple:
<% if #reviews.any? %>
<% #reviews.each do |review| %>
...
<% end %>
<% end %>
--
Data
The bottom line is that you need to have data in your database in order to populate the various variables / objects you wish to display in your application
The problem for a lot of people is that Heroku doesn't maintain the same database as the your local system, hence if you expect data to be there, and there isn't, your system will invoke the exception you're seeing
The bottom line is that you'll either need some validation (to determine if the data you require is present), or you'll need to seed your production database with the required records for your application
I agree with Rich and here is an alternative workaround:
I use try for optional attributes like "first name" because i don't want to force users through validations to submit them:
<%= "#{review.user.first_name.try(:capitalize)} #{review.user.last_name.try(:capitalize)}." %>
This way it shouldn't throw exceptions weather there was an attribute or not
Related
I am following a tutorial and we are creating a partial to to display a collection of data, but it is not rendering, my rails server command prompt shows that the database transaction is succesful:
Started GET "/portfolios" for ::1 at 2019-05-09 11:52:03 -0500
Processing by PortfoliosController#index as HTML
Rendering portfolios/index.html.erb within layouts/portfolio
Portfolio Load (0.3ms) SELECT "portfolios".* FROM "portfolios"
↳ app/views/portfolios/index.html.erb:5
Rendered collection of portfolios/_portfolio_item.html.erb [11 times] (2.1ms)
Rendered portfolios/index.html.erb within layouts/portfolio (5.3ms)
Rendered shared/_nav.html.erb (0.8ms)
Completed 200 OK in 31ms (Views: 28.6ms | ActiveRecord: 0.3ms)
Here is my partial under portfolios/_portfolio_item.html.erb:
<p><%= link_to portfolio_item.title, portfolio_show_path(portfolio_item) %></p>
<p><%= portfolio_item.subtitle %></p>
<p><%= portfolio_item.body %></p>
<%= image_tag portfolio_item.thumb_image unless portfolio_item.thumb_image.nil? %>
<%= link_to "Edit", edit_portfolio_path(portfolio_item) %>
<%= link_to 'Delete Portfolio Item', portfolio_path(portfolio_item), method: :delete, data: { confirm: 'Are you sure?' } %>
My index view under portfolios/index.html.erb :
<h1>Portfolio Items</h1>
<%= link_to "Create New Item", new_portfolio_url %>
<%= render partial: 'portfolio_item', collection: #portfolio_items %>
And my portfolios_controller :
class PortfoliosController < ApplicationController
layout 'portfolio'
def index
#portfolio_items = Portfolio.all
end
def show
#portfolio_item = Portfolio.find(params[:id])
end
def new
#portfolio_item = Portfolio.new
3.times { #portfolio_item.technologies.build }
end
def create
#portfolio_item = Portfolio.new(portfolio_params)
respond_to do |format|
if #portfolio_item.save
format.html { redirect_to portfolios_path, notice: 'Your portfolio item is now live!' }
else
format.html { render :new }
end
end
end
def edit
#portfolio_item = Portfolio.find(params[:id])
end
def update
#portfolio_item = Portfolio.find(params[:id])
respond_to do |format|
if #portfolio_item.update(portfolio_params)
format.html { redirect_to portfolios_path, notice: 'The record was successfully updated.' }
else
format.html { render :edit }
end
end
end
def destroy
#portfolio_item = Portfolio.find(params[:id])
#portfolio_item.destroy
respond_to do |format|
format.html { redirect_to portfolios_url, notice: 'Portfolio was successfully destroyed.' }
end
end
private
def portfolio_params
params.require(:portfolio).permit(:title,
:subtitle,
:body,
:main_image,
:thumb_image,
technologies_attributes: [:name])
end
end
If there is anything further needed please let me know and thanks in advance!
I'm not familiar with the collection syntax bbut for a quick fix try:
## index.html.erb
<h1>Portfolio Items</h1>
<%= link_to "Create New Item", new_portfolio_url %>
<% #portfolio_items.each do |item| %>
<%= render partial: 'portfolio_item', portfolio_item: item %>
<% end %>
Or if you really want to be fancy, and your model is called Portfolio, rename your partial to portfolios/_portfolio.html.erb. That will let you do:
## index.html.erb
<h1>Portfolio Items</h1>
<%= link_to "Create New Item", new_portfolio_url %>
<% #portfolio_items.each do |item| %>
<%= render item %>
<% end %>
Make sure there is no CSS or javascript that is removing/hiding your views. Also make sure you actually have some instances(rows) of the portfolio in your database.
<%= render partial: 'portfolio_item', collection: #portfolio_items %>
Although your usage of collection in partial is correct you can try to pass local variables and see if it works, because collection usage is dependent on file/model names which could cause issues.
When you use collection: #portfolio_items then you get access to use #portfolio_items instance variable within the partial view (portfolios/_portfolio_item.html.erb in your case).You are passing #portfolio_items but not using it anywhere, instead you are using portfolio_item variable which is not available in the partial view.
You need to iterate over #portfolio_items in order to render your items. If you need to pass variables to your partial use locals. Update your portfolios/index.html.erb as below
<h1>Portfolio Items</h1>
<%= link_to "Create New Item", new_portfolio_url %>
<% #portfolio_items.each do |portfolio_item| %>
<%= render partial: 'portfolio_item', locals: { portfolio_item: portfolio_item } %>
<% end %>
I'm Working in OneMonth Rails, I mistakenly deleted a user pin with an id of 6 inside of the console. Now I'm unable to create a new pin on local host. How can I fix the "SystemStackError in PinsController#index" error that I'm receiving?
index.html.erb:
<div class="panel panel-default">
<div class="panel-heading">
<div class="panel-title">
<h1>Listing Pins</h1>
<table>
<thead>
<tr>
<th>Image</th>
<th>Description</th>
<th>User</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #pins.each do |pin| %>
<tr>
<td><%= image_tag pin.image.url(:medium) %></td>
<td><%= pin.description %></td>
<td><%= pin.user.email if pin.user %></td>
<td><%= link_to 'Show', pin %></td>
<% if pin.user == current_user %>
<td><%= link_to 'Edit', edit_pin_path(pin) %></td>
<td><%= link_to 'Destroy', pin, method: :delete, data: { confirm: 'Are you sure?' } %></td>
<% end %>
</tr>
<% end %>
</tbody>
</table>
<br>
<% if user_signed_in? %>
<%= link_to 'New Pin', new_pin_path %>
<% end %>
Here is the code that I've written in the new action within my pins_controller.rb file.
def new
#pin = current_user.pins.build
end
Here is the server log:
Started GET "/pins" for ::1 at 2016-04-25 14:49:20 -0500
Processing by PinsController#index as HTML
[1m[36mPin Load (0.0ms)[0m [1mSELECT "pins".* FROM "pins"[0m
Rendered pins/index.html.erb within layouts/application (4.0ms)
Completed 500 Internal Server Error in 17ms (ActiveRecord: 0.0ms)
SystemStackError (stack level too deep):
actionpack (4.2.6) lib/action_dispatch/middleware/reloader.rb:79
Rendered c:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/_source.erb (1.0ms)
Rendered c:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (2.0ms)
Rendered c:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (2.0ms)
Rendered c:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (79.0ms)
Rendered c:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/web-console-2.3.0/lib/web_console/templates/_markup.html.erb (1.0ms)
Rendered c:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/web-console-2.3.0/lib/web_console/templates/_inner_console_markup.html.erb within layouts/inlined_string (0.0ms)
Rendered c:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/web-console-2.3.0/lib/web_console/templates/_prompt_box_markup.html.erb within layouts/inlined_string (1.0ms)
Rendered c:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/web-console-2.3.0/lib/web_console/templates/style.css.erb within layouts/inlined_string (1.0ms)
Rendered c:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/web-console-2.3.0/lib/web_console/templates/console.js.erb within layouts/javascript (84.0ms)
Rendered c:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/web-console-2.3.0/lib/web_console/templates/main.js.erb within layouts/javascript (1.0ms)
Rendered c:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/web-console-2.3.0/lib/web_console/templates/error_page.js.erb within layouts/javascript (1.0ms)
Rendered c:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/web-console-2.3.0/lib/web_console/templates/index.html.erb (173.0ms)
Here is an image of the error I'm receiving from your last comment
Below is my pins_controller.rb file:
class PinsController < ApplicationController
before_action :set_pin, only: [:show, :edit, :update, :destroy]
before_action :correct_user, only: [:edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
def index
#pins = Pin.all
end
def show
end
def new
#pin = current_user.pins.build
end
def edit
end
def create
#pin = current_user.pins.build(pin_params)
if #pin.save
redirect_to #pin, notice: 'Pin was successfully created.'
else
render :new
end
end
def update
if #pin.update(pin_params)
redirect_to #pin, notice: 'Pin was successfully updated.'
else
render :'edit'
end
end
def destroy
#pin.destroy
redirect_to pins_url
end
private
# Use callbacks to share common setup or constraints between actions.
def set_pin
#pin = Pin.find(id: params[:id])
end
def current_user
#pins = current_user.pins.find_by(params[:id])
redirect_to pins_path, notice: "Not authorized to edit this pin" if #pin.nil?
end
# Never trust parameters from the scary internet, only allow the white list through.
def pin_params
params.require(:pin).permit(:description, :image)
end
end
Update your new method, Its supposed to be like this.
def new
#pin = Pin.new
end
def create
#pin = current_user.pins.build(YOUR PARAMS HERE)
end
Ruby on Rails 4
I have a form to edit a record. The form is identical to the create new record. (Except for the wording). When I click submit it gives, nilLNilClass. My code works for my updating my other records that don't involve a Join Table so I am not sure what is wrong.
The Form:
<%= form_for(#test) do |f| %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :type %><br>
<%= f.text_field :type %>
</div>
<div class="field">
<%= f.label :category %><br>
<%= f.select :category, [ ["IP Voice Telephony", "ip_voice"], ["IP Video Surveillance", "ip_video_surveillance"], ["IP Video Telephony", "ip_video_telephony"], ["Enterprise Gateways", "enterprise_gateways"], ["Consumer ATAs", "consumer_atas"], ["IP PBX", "ip_pbx"] ], {prompt: "Select Category"}, class: "input-lg", :id => "category" %>
</div>
<div class="field">
<%= f.label :description %><br>
<%= f.text_field :description %>
</div>
<div id="container" style="width:1140px; margin-left: auto; margin-right: auto;">
<button type="button" class="reset">Reset Search</button>
<table width="100%" class="tablesorter">
<thead>
<tr>
<th width="5%" class="filter-false"><input type="checkbox" onClick="toggle(this)"></th>
<th width="37%" data-placeholder="Search">Content</th>
<th width="10%" data-placeholder="Search">Type</th>
<th width="10%" data-placeholder="Search">Category</th>
<th width="10%" data-placeholder="Search">Product</th>
<th width="10%" data-placeholder="Search">User</th>
<th width="8%" data-placeholder="Search">Active</th>
</tr>
</thead>
<tbody>
<% #questions.each do |q| %>
<tr>
<td><%= check_box_tag "test[question_ids][]", q.id, #test.question_ids.include?(q.id) %></td>
<td><%= q.content %></td>
<td><%= q.question_type %></td>
<td><%= q.category %></td>
<td>GXP</td>
<td><%= q.user_id %></td>
<td><%= q.active %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
</div>
<div class="actions">
<%= f.submit "Update Test", class: "btn btn-lg btn-primary" %>
</div>
<% end %>
Controller:
before_action :set_test, only: [:show, :edit, :update, :destroy]
before_action :signed_in_user, only: [:index, :edit, :show, :update, :destroy]
def edit
#test = Test.find(params[:id])
#questions = Question.all
end
def update
respond_to do |format|
if #test.update(test_params)
format.html { redirect_to #test, notice: 'Test was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #test.errors, status: :unprocessable_entity }
end
end
end
def test_params
params.require(:test).permit(:name, :user_id, :type, :category, :description, :question_ids => [], questions_attributes: [ :id ] ).
merge user_id: current_user.id
end
Error:
Started PATCH "/tests/98" for 127.0.0.1 at 2014-05-20 10:12:58 -0400
Processing by TestsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"x=", "test"=>{"name"=>"one two three four, spelling YEah!!", "type"=>"", "category"=>"ip_voice", "description"=>"not so smart, wooops", "question_ids"=>["1"]}, "commit"=>"Update Test", "id"=>"98"}
Test Load (0.3ms) SELECT "tests".* FROM "tests" WHERE "tests"."id" = ? LIMIT 1 [["id", "98"]]
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = 'x' LIMIT 1
Completed 500 Internal Server Error in 6ms
NoMethodError (undefined method `update' for nil:NilClass):
app/controllers/tests_controller.rb:56:in `block in update'
app/controllers/tests_controller.rb:55:in `update'
This is line 56: if #test.update(test_params)
I did think it was wierd that I had to define #test in edit(). I also tried #test.save with same error. I am misunderstanding something.
You need to define #test in update action. Currently its not defined so its value is nil and you receive the error.
Add this line in update action, before calling #test.update:
#test = Test.find(params[:id])
I see that you have a before_action callback for setting test i.e., set_test. In that case, you don't need
#test = Test.find(params[:id])
in update action. All you need to do is add update action in before_action callback as:
before_action :set_test, only: [:show, :edit, :update, :destroy]
Also, I would suggest you to remove the #test setting from edit action as you have already added edit action in before_action callback
Finally, set_test (ideally private method) method should look like:
def set_test
#test = Test.find(params[:id])
end
You need to do like this in your controller
before_action :set_test, only: [:show,:edit,:update,:destroy] and at the end of your controller
private
def set_test
#test = Test.find(params[:id])
end
And also,update your edit method like this
def edit
##test = Test.find(params[:id]) remove this line you wont need it.
#questions = Question.all
end
OR
You can just follow #kirti Thorat's answer.
I'm trying to render a form with AJAX. The non-ajax version works fine, but the ajaxified version doesn't. The link to it is in the index.html.erb. The Webrick server shows:
Started GET "/categories/3/new_sub" for 127.0.0.1 at 2012-11-19 17:19:27 -0500
Processing by CategoriesController#new_sub as JS
Parameters: {"id"=>"3"}
Category Load (0.1ms) SELECT "categories".* FROM "categories" WHERE "categories"."id" = ? LIMIT 1 [["id", "3"]]
Rendered categories/_form.html.erb (1.8ms)
Rendered categories/new_sub.js.erb (3.6ms)
Completed 200 OK in 8ms (Views: 6.3ms | ActiveRecord: 0.1ms)
Here's my Category controller:
# GET /categories
# GET /categories.json
def index
#categories = Category.roots
respond_to do |format|
format.html # index.html.erb
format.json { render json: #categories }
end
end
# GET /categories/1/new_sub.html
# GET /categories/1/new_sub.js
def new_sub
#parent = Category.find(params[:id])
#category = Category.new
respond_to do |format|
format.html
format.js
end
end
index.html.erb:
<h1>Listing categories</h1>
<%= recurse_categories(#categories) %>
<br />
<%= link_to 'New Category', new_category_path %>
recurse_categories helper:
def recurse_categories(cats)
s = "<ul>"
cats.each do |cat|
s << "<li id=\"#{cat.id}\">#{link_to cat.name, new_sub_category_path(cat), remote: true}</li>"
if cat.has_children?
s << recurse_categories(cat.children)
end
end
s << "</ul>"
s.html_safe
end
new_sub.js.erb:
$('ul').after(<%= render partial: "form", locals: { parent: #parent, category: #category } %>);
_form.html.erb:
<%= form_for(category) do |f| %>
<div class="field">
<%= f.text_field :name %>
<%= f.hidden_field :ancestry, value: "#{parent.ancestry + '/' + parent.id.to_s}" %>
<%= f.submit "Create subcategory" %>
</div>
<% end %>
Your "ul" tag is under category error's condition block. Are you sure you want to append your response in "error_explanation" div.
You can have an span tag and use it in new_sub.js.erb
<div class="field">
<span id="subcat"/>
<%= f.text_field :name %>
<%= f.hidden_field :ancestry, value: "#{parent.ancestry + '/' + parent.id.to_s}" %>
<%= f.submit "Create subcategory" %>
Fixed it! I just forgot quotation marks around the jquery selector and parameter, DUH!
I am getting an error
Started POST "/actions" for 127.0.0.1 at 2012-10-29 15:04:01 +0600
Processing by ActionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"lfHYF3EQn1/lMReK3alX3NsGa4wSMejC/0fEeoAFYUY=", "commit"=>"Create Action"}
Completed 500 Internal Server Error in 1ms
NoMethodError (undefined method `stringify_keys' for "create":String):
app/controllers/actions_controller.rb:43:in `new'
app/controllers/actions_controller.rb:43:in `create'
This code is totally generated by Rails, and i do not understand why it doesnt work
Here is model
class Action < ActiveRecord::Base
attr_accessible :name, :user_id
end
Here is controller part
# GET /actions/new
# GET /actions/new.json
def new
#action = Action.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #action }
end
end
def create
#action = Action.new(params[:action]) # here we get an error !
respond_to do |format|
if #action.save
format.html { redirect_to #action, notice: 'Action was successfully created.' }
format.json { render json: #action, status: :created, location: #action }
else
format.html { render action: "new" }
format.json { render json: #action.errors, status: :unprocessable_entity }
end
end
end
And here is the form code
<%= form_for(#action) do |f| %>
<% if #action.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#action.errors.count, "error") %> prohibited this action from being saved:</h2>
<ul>
<% #action.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :user_id %><br />
<%= f.number_field :user_id %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
When i press post, firebug shows this request parameters
utf8:✓
authenticity_token:lfHYF3EQn1/lMReK3alX3NsGa4wSMejC/0fEeoAFYUY=
action[name]:sdf
action[user_id]:23
commit:Create Action
if i understand correctly this must work and rails must turn action[name] and action[user_id] into hash table and place it into parameters[:action], then Action.new get this hash table as parameter. What is wrong ?
Ah, I know. You have a name clash.
action is a reserved name. Along with controller, id and maybe others. Use another name for your form.
When you post to /actions/create, then params[:controller] should be 'posts' and params[:action] should be 'create'. These params are assigned by Rails.
in your params you get params[:controller] = controller_name and params[:action] = action_name
In your case you are creating Action abject from action_name and not the params for object action. Try to use different name in params for object params.