I defined my route and controller actions correctly. Still I'm getting a no method error.
Here is my code:
Route:
get "/restaurants", to: "restaurants#index"
Controller action:
def index
resto = Restaurant.all
render json: resto,status: :ok
end
here is my error in the browser:
NoMethodError in RestaurantsController#index
undefined method `type' for #<Restaurant:0x00007fb711a07628>
Extracted source (around line #4):
def index
resto=Restaurant.all
( render json: resto,status: :ok) # this is the line throwing error
end
end
And here is the problem in the console
Use Ctrl-C to stop
Started GET "/restaurants" for ::1 at 2022-08-16 22:26:25 +0530
(0.7ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
Processing by RestaurantsController#index as HTML
Restaurant Load (1.2ms) SELECT "restaurants".* FROM "restaurants"
↳ app/controllers/restaurants_controller.rb:4:in `index'
[active_model_serializers] Rendered ActiveModel::Serializer::CollectionSerializer with ActiveModelSerializers::Adapter::Attributes (12.1ms)
Completed 500 Internal Server Error in 38ms (ActiveRecord: 7.5ms | Allocations: 17269)
I'm new to Ruby on Rails. Just getting my head around modelling relationships and how to build CRUD with them. I'd like advice or suggestions on how to fix this problem.
In my system, a support user (student) has private support sessions (like classes) with their support worker (tutor). Here's how the system will be used: a support worker will log in, select a service user they work with, and record a support session, which includes things like how long the session lasted for and where it took place. Eventually, the system will produce time-sheets that can be used to invoice for the tutor's work in these private support sessions.
I'm not quite sure how to interact with this at a controller level. So far I've built my model and scaffolds - now I'm customising them.
I've been using the official tutorial to help me get started at: https://guides.rubyonrails.org/v3.2.8/getting_started.html but I think I've gone beyond that now.
# Models
# Not entirely sure inverse_of is appropriate but several tutorials suggested it's worth putting in
class ServiceUser < ApplicationRecord
has_many :support_sessions, inverse_of: :service_user
has_many :support_workers, through: :support_sessions
end
class SupportWorker < ApplicationRecord
has_many :support_sessions, inverse_of: :support_worker
has_many :service_users, through: :support_sessions
class SupportSession < ApplicationRecord
belongs_to :support_worker, inverse_of: :support_sessions
belongs_to :service_user, inverse_of: :support_sessions
end
# Controller
class SupportSessionsController < ApplicationController
# POST /support_sessions
# POST /support_sessions.json
def create
# Auto-generated line:
#support_session = SupportSession.new(support_session_params)
# Get service_user_id from query string
#service_user = ServiceUser.find(params[:service_user_id])
# Lifted from RoR 'Getting started' article
#support_session = #service_user.support_sessions.create(params[:service_user])
respond_to do |format|
if #support_session.save
#format.html { redirect_to #support_session, notice: 'Support session was successfully created.' }
format.html { redirect_to service_users_url, notice: 'Support session was successfully created.' }
format.json { render :show, status: :created, location: #support_session }
else
format.html { render :new }
format.json { render json: #support_session.errors, status: :unprocessable_entity }
end
end
end
end
# Service user view/HTML form
# This is rendered as a partial on the service user's show.html.erb view
# select_support_workers() helper retrieves a list of ALL support workers in the system and the control value is the support_worker_id
<%= form_for([#service_user, #service_user.support_sessions.build]) do |f| %>
<tr>
<td>
<%= select_support_workers(f) %>
</td>
<td>
<%= f.text_field :location %>
</td>
<td>
<%= f.text_field :mode_of_delivery %>
</td>
<td>
<%= f.text_field :started_at %>
</td>
<td>
<%= f.text_field :ended_at %>
</td>
<td>
<%= f.text_field :total_breaks %>
</td>
<td>
<%= f.submit 'Save session' %>
</td>
</tr>
<% end %>
When I submit the form (which is being rendered as a partial on the service_user view show page), I seem to be ending up in the 'else' part of the if #support_session.save logic.
Error shown in my web browser is:
NameError in SupportSessions#create
Showing /Users/chris/git-local/timesheets/app/views/support_sessions/new.html.erb where line #5 raised:
undefined local variable or method `support_sessions_path' for #<#<Class:0x00007feb3412d028>:0x00007feb34163268>
Did you mean? #support_session
Extracted source (around line #5):
3 <%= render 'form', support_session: #support_session %>
4
5 <%= link_to 'Back', support_sessions_path %>
Rails.root: /Users/chris/git-local/timesheets
Application Trace | Framework Trace | Full Trace
app/views/support_sessions/new.html.erb:5:in `_app_views_support_sessions_new_html_erb__485411543567831194_70324083953220'
app/controllers/support_sessions_controller.rb:46:in `block (2 levels) in create'
app/controllers/support_sessions_controller.rb:40:in `create'
Request
Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"/xd16JX3LBjA7+9DVfnHwnJziucJkaICaWg/Sd6TK2rDOrugMcZu0r5qr6SO0TfqvXzzhBqvkydMIQqXp2NtrQ==",
"support_session"=>{"support_worker_id"=>"3", "location"=>"", "mode_of_delivery"=>"", "started_at"=>"", "ended_at"=>"", "total_breaks"=>""},
"commit"=>"Save session",
"service_user_id"=>"1"}
Console output
Started GET "/service_users/" for ::1 at 2019-05-31 07:58:29 +0100
(0.5ms) SET NAMES utf8, ##SESSION.sql_mode = CONCAT(CONCAT(##sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'), ##SESSION.sql_auto_is_null = 0, ##SESSION.wait_timeout = 2147483
↳ /Users/chris/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/log_subscriber.rb:98
Processing by ServiceUsersController#index as HTML
Started GET "/service_users/4" for ::1 at 2019-05-31 07:58:29 +0100
Rendering service_users/index.html.erb within layouts/application
(0.6ms) SET NAMES utf8, ##SESSION.sql_mode = CONCAT(CONCAT(##sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'), ##SESSION.sql_auto_is_null = 0, ##SESSION.wait_timeout = 2147483
↳ /Users/chris/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/log_subscriber.rb:98
ServiceUser Load (0.7ms) SELECT `service_users`.* FROM `service_users`
Processing by ServiceUsersController#show as HTML
↳ app/views/service_users/index.html.erb:22
Parameters: {"id"=>"4"}
Rendered service_users/index.html.erb within layouts/application (7.6ms)
ServiceUser Load (2.4ms) SELECT `service_users`.* FROM `service_users` WHERE `service_users`.`id` = 4 LIMIT 1
↳ app/controllers/service_users_controller.rb:69
Rendering service_users/show.html.erb within layouts/application
SupportSession Load (0.9ms) SELECT `support_sessions`.* FROM `support_sessions` WHERE `support_sessions`.`service_user_id` = 4
↳ app/views/service_users/show.html.erb:18
Rendered collection of templates [0 times] (0.0ms)
SupportWorker Load (1.2ms) SELECT `support_workers`.* FROM `support_workers` ORDER BY `support_workers`.`given_name` ASC
↳ app/helpers/support_sessions_helper.rb:15
Rendered support_sessions/_form.html.erb (7.5ms)
Rendered service_users/show.html.erb within layouts/application (15.6ms)
Completed 200 OK in 94ms (Views: 91.2ms | ActiveRecord: 0.7ms)
Completed 200 OK in 115ms (Views: 105.7ms | ActiveRecord: 4.5ms)
Started GET "/service_users/" for ::1 at 2019-05-31 07:58:30 +0100
Processing by ServiceUsersController#index as HTML
Started GET "/service_users/4" for ::1 at 2019-05-31 07:58:30 +0100
Rendering service_users/index.html.erb within layouts/application
Processing by ServiceUsersController#show as HTML
ServiceUser Load (1.5ms) SELECT `service_users`.* FROM `service_users`
Parameters: {"id"=>"4"}
↳ app/views/service_users/index.html.erb:22
Rendered service_users/index.html.erb within layouts/application (5.9ms)
ServiceUser Load (2.2ms) SELECT `service_users`.* FROM `service_users` WHERE `service_users`.`id` = 4 LIMIT 1
↳ app/controllers/service_users_controller.rb:69
Rendering service_users/show.html.erb within layouts/application
SupportSession Load (0.8ms) SELECT `support_sessions`.* FROM `support_sessions` WHERE `support_sessions`.`service_user_id` = 4
↳ app/views/service_users/show.html.erb:18
Rendered collection of templates [0 times] (0.0ms)
SupportWorker Load (1.3ms) SELECT `support_workers`.* FROM `support_workers` ORDER BY `support_workers`.`given_name` ASC
↳ app/helpers/support_sessions_helper.rb:15
Rendered support_sessions/_form.html.erb (5.5ms)
Rendered service_users/show.html.erb within layouts/application (12.1ms)
Completed 200 OK in 126ms (Views: 122.0ms | ActiveRecord: 1.5ms)
Completed 200 OK in 108ms (Views: 100.0ms | ActiveRecord: 4.3ms)
Started GET "/service_users/4" for ::1 at 2019-05-31 07:58:34 +0100
Started GET "/service_users/4" for ::1 at 2019-05-31 07:58:34 +0100
Processing by ServiceUsersController#show as HTML
Parameters: {"id"=>"4"}
Processing by ServiceUsersController#show as HTML
Parameters: {"id"=>"4"}
ServiceUser Load (1.3ms) SELECT `service_users`.* FROM `service_users` WHERE `service_users`.`id` = 4 LIMIT 1
↳ app/controllers/service_users_controller.rb:69
ServiceUser Load (1.5ms) SELECT `service_users`.* FROM `service_users` WHERE `service_users`.`id` = 4 LIMIT 1
↳ app/controllers/service_users_controller.rb:69
Rendering service_users/show.html.erb within layouts/application
Rendering service_users/show.html.erb within layouts/application
SupportSession Load (1.5ms) SELECT `support_sessions`.* FROM `support_sessions` WHERE `support_sessions`.`service_user_id` = 4
↳ app/views/service_users/show.html.erb:18
SupportSession Load (0.7ms) SELECT `support_sessions`.* FROM `support_sessions` WHERE `support_sessions`.`service_user_id` = 4
Rendered collection of templates [0 times] (0.0ms)
↳ app/views/service_users/show.html.erb:18
Rendered collection of templates [0 times] (0.0ms)
SupportWorker Load (1.4ms) SELECT `support_workers`.* FROM `support_workers` ORDER BY `support_workers`.`given_name` ASC
↳ app/helpers/support_sessions_helper.rb:15
SupportWorker Load (0.7ms) SELECT `support_workers`.* FROM `support_workers` ORDER BY `support_workers`.`given_name` ASC
↳ app/helpers/support_sessions_helper.rb:15
Rendered support_sessions/_form.html.erb (5.7ms)
Rendered service_users/show.html.erb within layouts/application (11.7ms)
Rendered support_sessions/_form.html.erb (5.8ms)
Rendered service_users/show.html.erb within layouts/application (12.6ms)
Completed 200 OK in 80ms (Views: 71.4ms | ActiveRecord: 4.2ms)
Completed 200 OK in 82ms (Views: 74.2ms | ActiveRecord: 2.9ms)
Started POST "/service_users/4/support_sessions" for ::1 at 2019-05-31 07:58:35 +0100
Processing by SupportSessionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"KZGBtom/9t6vYu5FyPRq3xA3Xmb6hkzG8LEA7c/qmOkUZGmtslduK+l2as5chNz7w4ikC+5fHRYh3Ak2IZwIvA==", "support_session"=>{"support_worker_id"=>"3", "location"=>"", "mode_of_delivery"=>"", "started_at"=>"", "ended_at"=>"", "total_breaks"=>""}, "commit"=>"Save session", "service_user_id"=>"4"}
ServiceUser Load (0.5ms) SELECT `service_users`.* FROM `service_users` WHERE `service_users`.`id` = 4 LIMIT 1
↳ app/controllers/support_sessions_controller.rb:33
(0.3ms) BEGIN
↳ app/controllers/support_sessions_controller.rb:36
(0.3ms) ROLLBACK
↳ app/controllers/support_sessions_controller.rb:36
(0.2ms) BEGIN
↳ app/controllers/support_sessions_controller.rb:41
(0.2ms) ROLLBACK
↳ app/controllers/support_sessions_controller.rb:41
Rendering support_sessions/new.html.erb within layouts/application
SupportWorker Load (0.5ms) SELECT `support_workers`.* FROM `support_workers` ORDER BY `support_workers`.`given_name` ASC
↳ app/helpers/support_sessions_helper.rb:15
Rendered support_sessions/_form.html.erb (3.9ms)
Rendered support_sessions/new.html.erb within layouts/application (324.5ms)
Completed 500 Internal Server Error in 336ms (ActiveRecord: 2.0ms)
ActionView::Template::Error (undefined local variable or method `support_sessions_path' for #<#<Class:0x00007ffb0925c658>:0x00007ffb083fa100>
Did you mean? #support_session):
2:
3: <%= render 'form', support_session: #support_session %>
4:
5: <%= link_to 'Back', support_sessions_path %>
app/views/support_sessions/new.html.erb:5:in `_app_views_support_sessions_new_html_erb___2840892112036112501_70358075950960'
app/controllers/support_sessions_controller.rb:46:in `block (2 levels) in create'
app/controllers/support_sessions_controller.rb:40:in `create'
# Crebs:timesheets chris$ rake routes -c support_session
Prefix Verb URI Pattern Controller#Action
service_user_support_sessions GET /service_users/:service_user_id/support_sessions(.:format) support_sessions#index
POST /service_users/:service_user_id/support_sessions(.:format) support_sessions#create
new_service_user_support_session GET /service_users/:service_user_id/support_sessions/new(.:format) support_sessions#new
edit_service_user_support_session GET /service_users/:service_user_id/support_sessions/:id/edit(.:format) support_sessions#edit
service_user_support_session GET /service_users/:service_user_id/support_sessions/:id(.:format) support_sessions#show
PATCH /service_users/:service_user_id/support_sessions/:id(.:format) support_sessions#update
PUT /service_users/:service_user_id/support_sessions/:id(.:format) support_sessions#update
DELETE /service_users/:service_user_id/support_sessions/:id(.:format) support_sessions#destroy
You have nested routes for support_sessions resource, so instead of
<%= link_to 'Back', support_sessions_path %>
you should use code like this to build correct path:
<%= link_to 'Back', [#service_user, :support_sessions] %>
or maybe like this one:
<%= link_to 'Back', service_user_support_sessions_path(#service_user) %>
Here's the code that got things working. Doesn't seem to work very well with validation but the data submits.
def create
#render plain: params[:support_session].inspect
# Auto-generated line:
##support_session = SupportSession.new(support_session_params)
# Get service_user_id from query string
# This is so each new record submitted can get the id of the service_user in question
#service_user = ServiceUser.find(params[:service_user_id])
# Copied from RoR 'Getting started' article: https://guides.rubyonrails.org/getting_started.html
# This calls the create method on #service_user.support_session (rather than #service_user alone)
# so the link is made between the service_user and the support_session
# Calls private method below to safeguard input parameters (only permitted ones)
#support_session = #service_user.support_sessions.create(support_session_params)
#redirect_to service_user_path(#service_user)
respond_to do |format|
if #support_session.save
#if #support_session
#if #service_user.support_sessions.create(support_session_params)
#if #service_user.support_sessions.new(support_session_params)
#format.html { redirect_to #support_session, notice: 'Support session was successfully created.' }
format.html { redirect_to #service_user, notice: 'Support session was successfully created.' }
format.json { render :show, status: :created, location: #support_session }
else
#format.html { render :show }
format.html { redirect_to service_user_path(#service_user), notice: 'There was an error!' }
format.json { render json: #support_session.errors, status: :unprocessable_entity }
end
end
end
If I have a url like localhost:3000?id=2 what do I need to change to get my AJAX call to use the param?
page_controller.rb
class PageController < ApplicationController
def index
#pId = params[:id]
#p = Plant.where(id: #pId)
respond_to do |format|
format.json { render json: #p.to_json }
format.html
end
end
end
page.coffee
$ ->
$.ajax
dataType: 'json'
url: 'index.json'
success: (data) ->
alert "Data #{JSON.parse(data)} ---"
development.log for one page load
Processing by PageController#index as HTML
Parameters: {"id"=>"2"}
Rendering page/index.html.erb within layouts/application
[1m[36mPlant Load (1.0ms)[0m [1m[34mSELECT "plants".* FROM "plants" WHERE "plants"."id" = $1[0m [["id", 2]]
Rendered page/index.html.erb within layouts/application (3.0ms)
Completed 200 OK in 80ms (Views: 69.5ms | ActiveRecord: 1.0ms)
Started GET "/index.json" for ::1 at 2017-01-26 08:07:18 -0800
Processing by PageController#index as JSON
[1m[36mPlant Load (1.0ms)[0m [1m[34mSELECT "plants".* FROM "plants" WHERE "plants"."id" IS NULL[0m
Completed 200 OK in 5ms (Views: 0.1ms | ActiveRecord: 1.0ms)
This is just a very basic example taken from a much more complicated piece of code. Everything in my original code works except for when I'm trying to access to param.
update 1
routes.rb
Rails.application.routes.draw do
get 'index' => 'page#index'
root "page#index"
end
Your URI for the Ajax request doesn't include the parameter. You're making a call to index.json and not index.json?id=1
I am trying to use the next page token from the first page results that are retrieved by the call to the Google Places, using the following code:
def pins_in_area
#client = GooglePlaces::Client.new('api_key_XXXXX')
#results = #client.spots(params[:lat], params[:long], :radius => params[:radius])
puts #results
next_page_token = #results.last.nextpagetoken
puts next_page_token #spots_by_pagetoken
next_spots = #client.spots_by_pagetoken(next_page_token)
puts next_spots
...
end
But, I encounter the following error, not sure why:
Completed 500 Internal Server Error in 258ms (ActiveRecord: 0.0ms)
GooglePlaces::InvalidRequestError (GooglePlaces::InvalidRequestError):
app/controllers/api/v1/pins_controller.rb:89:in `pins_in_area'
Rendered /usr/local/rvm/gems/ruby-2.2.1/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/_source.erb (13.1ms)
Rendered /usr/local/rvm/gems/ruby-2.2.1/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (35.1ms)
Rendered /usr/local/rvm/gems/ruby-2.2.1/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (2.0ms)
Rendered /usr/local/rvm/gems/ruby-2.2.1/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (101.1ms)
Okay, here's the deal I can't figure out at the moment.
So, I have this action looking like this:
def get
#page = Page.find_by_title(params[:title])
respond_to do |format|
format.html # get.html.erb
format.js # get.js.coffee
end
end
Which, depending on whether it's an AJAX call or a normal GET request, the renders either get.html.erb or get.js.coffee.
In development, that is, as shown by the following log entry:
Started GET "/pages/medien/get" for 127.0.0.1 at 2011-12-11 18:58:31 +0100
Processing by PagesController#get as JS
Parameters: {"title"=>"medien"}
Rendered pages/_get.html.erb (153.0ms)
Rendered pages/get.js.coffee (1185.0ms)
Completed 200 OK in 1230ms (Views: 1220.0ms | ActiveRecord: 5.0ms)
In production the same request and same code results in a log entry like this:
Started GET "/pages/medien/get/" for 91.11.86.230 at 2011-12-11 18:57:44 +0100
Processing by PagesController#get as JS
Parameters: {"title"=>"medien"}
Read fragment views/mypage/pages/medien/get (0.1ms)
Rendered pages/_get.html.erb (0.8ms)
Rendered pages/get.html.erb (0.9ms)
Completed 200 OK in 2ms (Views: 1.5ms | ActiveRecord: 0.2ms)
I simply don't get why it's even stating that it's processing it as JavaScript but then does not execute the javascript in get.js.coffee without even throwing an error!