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
Related
I'm migrating a Rails 3 app to Rails 6 and using the activerecord-reputation-system gem for counting votes. The app ran without issues before migrating.
When I run the app on localhost, user sign-up, etc works fine, but when I go into the Recommendations section of the app, I get the following error:
ActiveRecord::StatementInvalid in Recommendations#index
PG::SyntaxError: ERROR: syntax error at end of input
LINE 1: ...ation_name = 'votes' AND rs_reputations.active = TRUE WHERE
Recommendations Model:
class Recommendation < ActiveRecord::Base
has_reputation :votes, source: :user, aggregated_by: :sum
belongs_to :user
end
Recommendations Controller:
class RecommendationsController < ApplicationController
before_action :set_recommendation, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!
def index
#category = ["product", "marketing", "business", "team", "general"]
#recommendations = Recommendation.find_with_reputation(:votes, :all)
#product = Recommendation.where(category: "Product").order("votes DESC")
#marketing = Recommendation.where(category: "Marketing").order("votes DESC")
#business = Recommendation.where(category: "Business").order("votes DESC")
#team = Recommendation.where(category: "Team/culture").order("votes DESC")
#general = Recommendation.where(category: "General").order("votes DESC")
end
and Recommendations Index view:
<h3>Recommendations</h3>
<h5>(<%= link_to new_recommendation_path, "data-no-turbolink" => true do %>
<span class="glyphicon glyphicon-plus"></span> New Recommendation
<% end %>)</h5>
<table class="table table-striped">
<tr>
<th>Submitted</th>
<th>Category</th>
<th>Title</th>
<th>Description</th>
<th>Votes</th>
</tr>
<% #recommendations.each do |recommendation| %>
<tr>
<td><%= recommendation.created_at.strftime("%B %d, %Y") %><br>
<small>    by: <strong><%= recommendation.user.name %></strong></td>
<td><%= recommendation.category %></td>
<td><%= recommendation.title %></td>
<td><%= recommendation.description %></td>
<td>
<% if current_user && recommendation.has_evaluation?(:votes, current_user) %>
<%= link_to downvote_recommendation_path(recommendation), method: "post" do %>
<span class="glyphicon glyphicon-heart"></span>
<% end %>
<% else %>
<%= link_to vote_recommendation_path(recommendation, type: "up"), method: "post" do %>
<span class="glyphicon glyphicon-heart-empty"></span>
<% end %>
<% end %>
(<%= recommendation.reputation_for(:votes).to_i %>)
</td>
</tr>
<% end %>
</table>
The error is being thrown at:
<% #recommendations.each do |recommendation| %>
From the terminal I see:
Started GET "/recommendations" for ::1 at 2019-12-29 10:06:57 -0800
(3.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
Processing by RecommendationsController#index as HTML
User Load (6.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
Rendering recommendations/index.html.erb within layouts/application
Recommendation Load (0.5ms) SELECT recommendations.*, COALESCE(rs_reputations.value, 0) AS votes FROM "recommendations" LEFT JOIN rs_reputations ON recommendations.id = rs_reputations.target_id AND rs_reputations.target_type = 'Recommendation' AND rs_reputations.reputation_name = 'votes' AND rs_reputations.active = TRUE WHERE
Rendered recommendations/index.html.erb within layouts/application (Duration: 3.0ms | Allocations: 1597)
Completed 500 Internal Server Error in 49ms (ActiveRecord: 17.2ms | Allocations: 21303)
ActionView::Template::Error (PG::SyntaxError: ERROR: syntax error at end of input
LINE 1: ...ation_name = 'votes' AND rs_reputations.active = TRUE WHERE
Was able to solve by changing controller:
#recommendations = Recommendation.find_with_reputation(:votes, :all)
to
#recommendations = Recommendation.with_reputation(:votes)
changing find_with_reputation to with_reputation solved it
Edit: Main problem was that when I added the reference fields, I did theater:reference and not theater:references so the field was not marked as a foreign key. Once I undid those migrations and redid them correctly, I was able to make this work.
In my showtimes controller, I am trying to automatically set the theater id to whatever theater owns the screen that the user inputed, but when I try to save it as an integer or a string, I get an error. Yet, when I try to save it as a theater object, I get "Unpermitted parameter: theater" from the console and a "Theater must exist" error from the rails application.
showtimes_controller:
class ShowtimesController < ApplicationController
before_action :set_theater, only: [:create, :edit]
before_action :set_showtime, only: [:show, :edit, :update, :destroy]
# GET /showtimes
# GET /showtimes.json
def index
#showtimes = Showtime.all
end
# GET /showtimes/1
# GET /showtimes/1.json
def show
end
# GET /showtimes/new
def new
#showtime = Showtime.new
end
# GET /showtimes/1/edit
def edit
end
# POST /showtimes
# POST /showtimes.json
def create
#showtime = Showtime.new(showtime_params)
respond_to do |format|
if #showtime.save
format.html { redirect_to #showtime, notice: 'Showtime was successfully created.' }
format.json { render :show, status: :created, location: #showtime }
else
format.html { render :new }
format.json { render json: #showtime.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /showtimes/1
# PATCH/PUT /showtimes/1.json
def update
respond_to do |format|
if #showtime.update(showtime_params)
format.html { redirect_to #showtime, notice: 'Showtime was successfully updated.' }
format.json { render :show, status: :ok, location: #showtime }
else
format.html { render :edit }
format.json { render json: #showtime.errors, status: :unprocessable_entity }
end
end
end
# DELETE /showtimes/1
# DELETE /showtimes/1.json
def destroy
#showtime.destroy
respond_to do |format|
format.html { redirect_to showtimes_url, notice: 'Showtime was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_showtime
#showtime = Showtime.find(params[:id])
end
def set_theater
screenInfo = Screen.where("id = ?", params[:showtime][:screen])
params['showtime']['theater'] = Theater.find(screenInfo[0]['theater_id'])
end
# Never trust parameters from the scary internet, only allow the white list through.
def showtime_params
params.require(:showtime).permit(:date, :time, :archived, :movie_id, :theater, :screen)
end
end
showtimes model:
class Showtime < ApplicationRecord
belongs_to :movie
belongs_to :theater
end
Showtimes _form
<%= form_for(showtime) do |f| %>
<% if showtime.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(showtime.errors.count, "error") %> prohibited this showtime from being saved:</h2>
<ul>
<% showtime.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :date %>
<%= f.date_select :date %>
</div>
<div class="field">
<%= f.label :time %>
<%= f.time_select :time %>
</div>
<div class="field">
<%= f.label :archived %>
<%= f.check_box :archived %>
</div>
<div class="field">
<%= f.label :movie_id %>
<%= f.text_field :movie_id %>
</div>
<div class="field">
<%= f.label :screen %>
<%= f.text_field :screen %>
</div>
<%= f.hidden_field :theater, :value => "" %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Error when trying to save as integer:
Theater(#70015922237640) expected, got Fixnum(#11723820)
Error when trying to save as string:
Theater(#70015868755420) expected, got String(#11739240)
Logs when trying to save as Theater object:
Started POST "/showtimes" for IP at 2016-11-08 20:22:37 +0000
Processing by ShowtimesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"nENPV5d6YRXdcx3H+Xa9ZypGtyFlaTg+zyENGB10TmW9OyWxLR9Dsl7nDoG9irq+3qApiNA2/oEqL5RZ0SXorA==", "showtime"=>{"date(1i)"=>"2016", "date(2i)"=>"11", "date(3i)"=>"8", "time(1i)"=>"2016", "time(2i)"=>"11", "time(3i)"=>"8", "time(4i)"=>"20", "time(5i)"=>"22", "archived"=>"0", "movie_id"=>"2", "screen"=>"1", "theater"=>""}, "commit"=>"Create Showtime"}
[1m[36mScreen Load (0.3ms)[0m [1m[34mSELECT "screens".* FROM "screens" WHERE (id = '1')[0m
[1m[36mTheater Load (0.2ms)[0m [1m[34mSELECT "theaters".* FROM "theaters" WHERE "theaters"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
Unpermitted parameter: theater
[1m[35m (0.1ms)[0m [1m[36mbegin transaction[0m
[1m[36mMovie Load (0.2ms)[0m [1m[34mSELECT "movies".* FROM "movies" WHERE "movies"."id" = ? LIMIT ?[0m [["id", 2], ["LIMIT", 1]]
[1m[35m (0.2ms)[0m [1m[31mrollback transaction[0m
Rendering showtimes/new.html.erb within layouts/application
Rendered showtimes/_form.html.erb (13.6ms)
Rendered showtimes/new.html.erb within layouts/application (16.4ms)
Completed 200 OK in 323ms (Views: 86.5ms | ActiveRecord: 3.9ms)
How the hell do I save this parameter?
Have you tried assigning your object to an instance variable, and assigning it before saving?
On your before_action
def set_theater
#theather = ... # Code to find the theather
end
On your create action
def create
#showtime = Showtime.new(showtime_params)
#showtime.theather = #theather
... # Code to save and handle errors
end
You use theater instead of theater_id in several places in your code, and you'll need to change it in all the places, in order for this to work.
Firstly - you can't select a theater in our form... html doesn't recognise a type of theaterand will not pass one through - so your form needs to pass the theater_id instead (which will be an integer that it happily can deal with).
# eg here make sure it's a theater_id
<%= f.hidden_field :theater_id, :value => #theater.id %>
next - your require/permit is probably what's throwing some errors - you need that to be theater_id as well:
def showtime_params
params.require(:showtime).permit(:date, :time, :archived, :movie_id, :theater_id, :screen)
end
Now you need to fetch the theater out, using the screen-info param - but also keep in mind that this might come through as nil some times (so a guard-clause is always good):
def set_theater
if params[:showtime].present? && params[:showtime][:screen_id].present?
screen_info = Screen.find(params[:showtime][:screen_id])
#theater = Theater.find(screenInfo.theater_id)
end
end
Note: I have updated naming-schemes to be rail-standard and removed the thing where you try to set the theatre in params as below:
params['showtime']['theater'] = Theater.find(screenInfo[0]['theater_id'])
I don't know what you're actually trying to do with this line of code, but whatever it is, params doesn't work that way - consider that params is "the set of things that were passed through to us from the user, and are then thrown away" - we don't use it to store new values that we create ion the controller. That's what #variables are for
Can you explain more what you're trying to do and we'll figure out the right way to do it :)
I am receiving a undefined method `name' for # error for my Rails project. I know that name is defined for events by double checking using my console, so I don't understand why it won't load. Here is some of my code:
Apps Show:
<h1><%= #app.title %></h1>
<h5>App URL: <%= #app.url %></h5>
<h5>App User_id: <%= #app.user_id %></h5>
<br>
<h2> Events </h2>
<% #events.each do |event| %>
<div>
<%= event.name %><span class="badge"><%= event.count %></span>
</div>
<% end %>
<br>
<%= link_to "Edit", edit_app_path(#app), class: 'btn btn-success' %>
Apps Controller:
class AppsController < ApplicationController
def create
#app = App.new(params.require(:app).permit(:title, :url))
#app.user_id = 1
if #app.save
flash[:notice] = "App was saved!"
redirect_to #app
else
flash[:error] = "There an error, oh noes!Please try again!"
render :new
end
end
def new
#app = App.new
end
def show
#app = App.find(params[:id])
#events = #app.events.group_by(&:name)
end
def index
#apps = App.all
end
def edit
#app = App.find(params[:id])
end
def update
#app = App.find(params[:id])
if #app.update_attributes(params.require(:app).permit(:title, :url))
flash[:notice] = "Application was updated."
redirect_to #app
else
flash[:error] = "There was an error saving the app. Please try again."
render :edit
end
end
def destroy
#app = App.find(params[:id])
if #app.destroy
flash[:notice] = "App was removed."
redirect_to #app
else
flash[:error] = "App couldn't be deleted. Try again."
redirect_to #app
end
respond_to do |format|
format.html
format.js
end
end
end
Events Seed:
create_table "events", force: :cascade do |t|
t.integer "app_id"
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
App Model:
class App < ActiveRecord::Base
belongs_to :user
has_many :events
end
Complete Error Log:
Completed 500 Internal Server Error in 19ms
ActionView::Template::Error (undefined method `name' for #<Array:0x007fcc53394af0>):
6: <h2> Events </h2>
7: <% #events.each do |event| %>
8: <div>
9: <%= event.name %><span class="badge"><%= event.count %></span>
10: </div>
11: <% end %>
12: <br>
app/views/apps/show.html.erb:9:in `block in _app_views_apps_show_html_erb__2949113196422864311_70257764571040'
app/views/apps/show.html.erb:7:in `each'
app/views/apps/show.html.erb:7:in `_app_views_apps_show_html_erb__2949113196422864311_70257764571040'
Rendered /Users/ericpark/.rvm/gems/ruby-2.2.0/gems/actionpack-4.2.0/lib/action_dispatch/middleware/templates/rescues/_source.erb (7.1ms)
Rendered /Users/ericpark/.rvm/gems/ruby-2.2.0/gems/actionpack-4.2.0/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (4.1ms)
Rendered /Users/ericpark/.rvm/gems/ruby-2.2.0/gems/actionpack-4.2.0/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (0.9ms)
Rendered /Users/ericpark/.rvm/gems/ruby-2.2.0/gems/actionpack-4.2.0/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb within rescues/layout (71.2ms)
Rendered /Users/ericpark/.rvm/gems/ruby-2.2.0/gems/web-console-2.1.3/lib/web_console/templates/_markup.html.erb (0.7ms)
Rendered /Users/ericpark/.rvm/gems/ruby-2.2.0/gems/web-console-2.1.3/lib/web_console/templates/style.css.erb within layouts/inlined_string (0.7ms)
Rendered /Users/ericpark/.rvm/gems/ruby-2.2.0/gems/web-console-2.1.3/lib/web_console/templates/_inner_console_markup.html.erb within layouts/inlined_string (0.5ms)
Rendered /Users/ericpark/.rvm/gems/ruby-2.2.0/gems/web-console-2.1.3/lib/web_console/templates/_prompt_box_markup.html.erb within layouts/inlined_string (0.3ms)
Rendered /Users/ericpark/.rvm/gems/ruby-2.2.0/gems/web-console-2.1.3/lib/web_console/templates/console.js.erb within layouts/javascript (69.6ms)
Rendered /Users/ericpark/.rvm/gems/ruby-2.2.0/gems/web-console-2.1.3/lib/web_console/templates/main.js.erb within layouts/javascript (0.4ms)
Rendered /Users/ericpark/.rvm/gems/ruby-2.2.0/gems/web-console-2.1.3/lib/web_console/templates/error_page.js.erb within layouts/javascript (0.7ms)
Rendered /Users/ericpark/.rvm/gems/ruby-2.2.0/gems/web-console-2.1.3/lib/web_console/templates/index.html.erb (156.5ms)
#events is hash you have to iterate like
<% #events.each do |event| %>
<div>
<%= event[0] %><span class="badge"><%= event[1].count %></span>
</div>
<% end %>
In cases like this, simple debug printing will reveal the problem. Is name not defined on #events when you think it should be? Are you sure that #events is what you think it is?
Add p #events line to your controller, retry the request and read the log. A piece of advice for the future. :)
The problem starts here:
#events = #app.events.group_by(&:name)
I'm pretty sure that output of group_by is a hash, where keys are different names and values are arrays of events which all have the same name. (depends on what exactly the implementation of group_by is, of course)
<% #events.each do |event| %>
event here is not an instance of Event class, but a two element array, [name, [event1, event2, ...]]. You should iterate this nested array to get real events, which do have the method you want.
<% #events.each do |name, events| %>
<%= name %> <%= events.length %>
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
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>