grape
grape copied to clipboard
NoMethodError in after callback inside Grape::Middleware::Formatter
I am getting Grape::Middleware::Formatter : undefined method `collect' for #<Stream:0x00007f685ce13270>
My code works fine, I have tested each line by my hand but if I run the whole API this error appears.
My code is as follow
@stream = Stream.new(stream_params)
@stream.location_id = get_location
@stream.user_id = @streamer.id
@stream.university = @university
@stream.category = @category
@stream.save!
status(200){
'message': 'successfully created the stream request'
}
@Bilal-Abbas-Gigalabs which version of Grape and Rack do you use?
rack (~> 2.0, >= 2.0.8)
grape (1.5.1)
activesupport
builder
dry-types (>= 1.1)
mustermann-grape (~> 1.0.0)
rack (>= 1.3.0)
rack-accept
grape-active_model_serializers (1.5.2)
active_model_serializers (>= 0.10.0)
grape (>= 0.8.0)
grape_devise_token_auth (0.1.4)
devise (>= 3.3)
devise_token_auth (>= 0.1.32)
grape (> 0.9.0)
grape_on_rails_routes (0.3.2)
rails (>= 3.1.1)
groupdate (5.2.1)
activesupport (>= 5)
i18n (1.8.5)
concurrent-ruby (~> 1.0)
I think this is because your method returns the stream somehow.
Noticing that status
does not take a block. Try this:
... # your code that does something to Stream
status 200
{ 'message': 'successfully created the stream request' }
Still getting the same error on above update !!!
Post the full stack please?
caught error of type NoMethodError in after callback inside Grape::Middleware::Formatter : undefined method `collect' for #<Stream:0x00007fdc60daa630>
NoMethodError (undefined method `collect' for #<Stream:0x00007fdc60daa630>):
activemodel (6.0.3.4) lib/active_model/attribute_methods.rb:432:in `method_missing'
grape (1.5.1) lib/grape/middleware/formatter.rb:47:in `block in build_formatted_response'
activesupport (6.0.3.4) lib/active_support/notifications.rb:182:in `instrument'
grape (1.5.1) lib/grape/middleware/formatter.rb:46:in `build_formatted_response'
grape (1.5.1) lib/grape/middleware/formatter.rb:30:in `after'
grape (1.5.1) lib/grape/middleware/base.rb:39:in `call!'
grape (1.5.1) lib/grape/middleware/base.rb:29:in `call'
grape (1.5.1) lib/grape/middleware/base.rb:36:in `call!'
grape (1.5.1) lib/grape/middleware/base.rb:29:in `call'
grape_devise_token_auth (0.1.4) lib/grape_devise_token_auth/middleware.rb:14:in `call'
grape (1.5.1) lib/grape/middleware/auth/base.rb:37:in `_call'
grape (1.5.1) lib/grape/middleware/auth/base.rb:19:in `call'
grape (1.5.1) lib/grape/middleware/error.rb:39:in `block in call!'
grape (1.5.1) lib/grape/middleware/error.rb:38:in `catch'
grape (1.5.1) lib/grape/middleware/error.rb:38:in `call!'
grape (1.5.1) lib/grape/middleware/base.rb:29:in `call'
rack (2.0.9) lib/rack/head.rb:12:in `call'
grape (1.5.1) lib/grape/endpoint.rb:231:in `call!'
grape (1.5.1) lib/grape/endpoint.rb:225:in `call'
grape (1.5.1) lib/grape/router/route.rb:58:in `exec'
grape (1.5.1) lib/grape/router.rb:116:in `process_route'
grape (1.5.1) lib/grape/router.rb:72:in `block in identity'
grape (1.5.1) lib/grape/router.rb:91:in `transaction'
grape (1.5.1) lib/grape/router.rb:70:in `identity'
grape (1.5.1) lib/grape/router.rb:55:in `block in call'
grape (1.5.1) lib/grape/router.rb:132:in `with_optimization'
grape (1.5.1) lib/grape/router.rb:54:in `call'
grape (1.5.1) lib/grape/api/instance.rb:167:in `call'
grape (1.5.1) lib/grape/api/instance.rb:71:in `call!'
grape (1.5.1) lib/grape/api/instance.rb:66:in `call'
grape (1.5.1) lib/grape/api.rb:68:in `call'
actionpack (6.0.3.4) lib/action_dispatch/routing/mapper.rb:19:in `block in <class:Constraints>'
actionpack (6.0.3.4) lib/action_dispatch/routing/mapper.rb:48:in `serve'
actionpack (6.0.3.4) lib/action_dispatch/journey/router.rb:49:in `block in serve'
actionpack (6.0.3.4) lib/action_dispatch/journey/router.rb:32:in `each'
actionpack (6.0.3.4) lib/action_dispatch/journey/router.rb:32:in `serve'
actionpack (6.0.3.4) lib/action_dispatch/routing/route_set.rb:834:in `call'
warden (1.2.9) lib/warden/manager.rb:36:in `block in call'
warden (1.2.9) lib/warden/manager.rb:34:in `catch'
warden (1.2.9) lib/warden/manager.rb:34:in `call'
rack (2.0.9) lib/rack/etag.rb:25:in `call'
rack (2.0.9) lib/rack/conditional_get.rb:38:in `call'
rack (2.0.9) lib/rack/head.rb:12:in `call'
activerecord (6.0.3.4) lib/active_record/migration.rb:567:in `call'
actionpack (6.0.3.4) lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'
activesupport (6.0.3.4) lib/active_support/callbacks.rb:101:in `run_callbacks'
actionpack (6.0.3.4) lib/action_dispatch/middleware/callbacks.rb:26:in `call'
actionpack (6.0.3.4) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (6.0.3.4) lib/action_dispatch/middleware/actionable_exceptions.rb:18:in `call'
actionpack (6.0.3.4) lib/action_dispatch/middleware/debug_exceptions.rb:32:in `call'
actionpack (6.0.3.4) lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
railties (6.0.3.4) lib/rails/rack/logger.rb:37:in `call_app'
railties (6.0.3.4) lib/rails/rack/logger.rb:26:in `block in call'
activesupport (6.0.3.4) lib/active_support/tagged_logging.rb:80:in `block in tagged'
activesupport (6.0.3.4) lib/active_support/tagged_logging.rb:28:in `tagged'
activesupport (6.0.3.4) lib/active_support/tagged_logging.rb:80:in `tagged'
railties (6.0.3.4) lib/rails/rack/logger.rb:26:in `call'
actionpack (6.0.3.4) lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
request_store (1.5.0) lib/request_store/middleware.rb:19:in `call'
actionpack (6.0.3.4) lib/action_dispatch/middleware/request_id.rb:27:in `call'
rack (2.0.9) lib/rack/runtime.rb:22:in `call'
activesupport (6.0.3.4) lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call'
actionpack (6.0.3.4) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (6.0.3.4) lib/action_dispatch/middleware/static.rb:126:in `call'
rack (2.0.9) lib/rack/sendfile.rb:111:in `call'
actionpack (6.0.3.4) lib/action_dispatch/middleware/host_authorization.rb:82:in `call'
rack-cors (1.1.1) lib/rack/cors.rb:100:in `call'
railties (6.0.3.4) lib/rails/engine.rb:527:in `call'
puma (4.3.7) lib/puma/configuration.rb:228:in `call'
puma (4.3.7) lib/puma/server.rb:713:in `handle_request'
puma (4.3.7) lib/puma/server.rb:472:in `process_client'
puma (4.3.7) lib/puma/server.rb:328:in `block in run'
puma (4.3.7) lib/puma/thread_pool.rb:134:in `block in spawn_thread'
I don't know how your Stream
object is making this to the formatter part. Your code above creates it, assigns it to some @stream
and then is done with it? Or are you returning it elsewhere? Post the complete API class?
Does the API return a result successfully without any of the stream = ...
code?
I think you'll have to put up something that reproduces the problem from here for us to help.
That is my end point
# ----------------------------------------------------
# POST /
# ----------------------------------------------------
#
desc 'Create stream request'
post '/' do
authenticate_api_admin_user!
init_create
@stream = Stream.new(stream_params)
@stream.location_id = get_location
@stream.user_id = @streamer.id
@stream.university = @university
@stream.category = @category
unless params[:user][:streamImage].nil?
s3 = Aws::S3::Resource.new(region:'eu-west-2')
extension = params[:user][:streamImage][:filename].split('.').last
filename = SecureRandom.uuid + "." + extension
image = s3.bucket('communy-file-storage').object("stream_images/" + filename)
image.upload_file(params[:user][:streamImage][:tempfile])
@stream.stream_image = image.public_url.to_s
end
set_temp_date_to_stream
survey = Survey.find(ActiveSupport::JSON.decode(params[:user][:survey])["id"]) if
ActiveSupport::JSON.decode(params[:user][:survey]).present?
@stream.survey = survey if survey.present?
@stream.save!
@notification = Notification.new()
@notification.title = "New Stream Request!"
@notification.text = "Your university admin has invited you for a stream."
@notification.type = Notification.types[:stream_request_from_university]
@notification.user_id = @streamer.id
@notification.save!
assign_secondary_categories
@stream_request = StreamRequest.new(stream_request_params)
@stream_request.save!
assign_time_ranges
status 200
{
'message': 'successfully created the stream request'
}
end
Follwoing are my helpers
helpers do
def stream_params
@stream_params ||= {
name: ActiveSupport::JSON.decode(params[:user][:title]),
overview: ActiveSupport::JSON.decode(params[:user][:description]),
publish_status: ActiveSupport::JSON.decode(params[:user][:isPublished]) ? 'broadcasted' : 'draft',
streamer_status: 'waiting',
agora_status: 'standby',
stream_type: ActiveSupport::JSON.decode(params[:user][:streamType]) == 'Webinar' ? 1 : 0,
repeat_stream: ActiveSupport::JSON.decode(params[:user][:repeatStream]).nil? ? 'None' :
ActiveSupport::JSON.decode(params[:user][:repeatStream])
}
end
def update_stream_params
@update_stream_params ||= {
name: ActiveSupport::JSON.decode(params[:user][:title]),
overview: ActiveSupport::JSON.decode(params[:user][:description]),
repeat_stream: ActiveSupport::JSON.decode(params[:user][:repeatStream]).nil? ? 'None' :
ActiveSupport::JSON.decode(params[:user][:repeatStream]),
category_id: ActiveSupport::JSON.decode(params[:user][:primaryCategory])
}
end
def stream_request_params
@stream_request_params ||= {
requester: current_api_admin_user,
requestee: @streamer,
status: ActiveSupport::JSON.decode(params[:user][:isPublished]) ? 'pending' : 'draft',
stream: @stream,
from_university: true
}
end
def location_params
@location_params ||= {
place: ActiveSupport::JSON.decode(params[:user][:location]),
university_id: @university.id
}
end
def init_create
@university = current_api_admin_user.profession_university
unless @university
error!('This user is not assigned to any university', 404, nil)
end
@streamer = User.find(ActiveSupport::JSON.decode(params[:user][:streamer])["id"])
unless @streamer
error!('Streamer can not find', 404, nil)
end
@category = Category.find(ActiveSupport::JSON.decode(params[:user][:primaryCategory]))
unless @category
error!('Category can not find', 404, nil)
end
end
def init_update
@stream = Stream.find(ActiveSupport::JSON.decode(params[:user][:id]))
unless @stream
error!("There is no stream with this id #{ActiveSupport::JSON.decode(params[:user][:id])}", 404, nil)
end
@stream_request = StreamRequest.find_by_stream_id(@stream.id)
unless @stream_request
error!('There is no stream_request about this stream', 404, nil)
end
@university = current_api_admin_user.profession_university
unless @university
error!('This user is not assigned to any university', 404, nil)
end
end
def get_location
location = Location.where(place: ActiveSupport::JSON.decode(params[:user][:location]))
.where(university_id: @university.id)
if location.empty?
location = Location.new(location_params)
location.save!
else
location = location.first
end
location.id
end
def set_temp_date_to_stream
favorite_time_range_option = ActiveSupport::JSON.decode(params[:user][:availableTimes]).find { |t| t["isFavorite"] }
unless favorite_time_range_option
error!('There should be at least one favorite available time', 404, nil)
end
@stream.starts_at = Time.at(favorite_time_range_option["startTs"]).to_datetime
@stream.ends_at = Time.at(favorite_time_range_option["endTs"]).to_datetime
end
def assign_time_ranges
@stream_request.time_ranges.clear
ActiveSupport::JSON.decode(params[:user][:availableTimes]).each do |time_range|
start_ts = Time.at(time_range["startTs"]).to_datetime
end_ts = Time.at(time_range["endTs"]).to_datetime
@stream_request.create_time_ranges(start_ts, end_ts, time_range["isFavorite"])
end
end
def assign_secondary_categories
if ActiveSupport::JSON.decode(params[:user][:secondaryCategories]).present?
secondary_categories = @stream.secondary_categories
secondary_categories.destroy_all
ActiveSupport::JSON.decode(params[:user][:secondaryCategories])&.each do |category|
next unless Category.find(category["id"])
SecondaryCategory.create(stream: @stream, category_id: category["id"])
end
end
end
end
and one model method
def create_time_ranges(start_hour, end_hour, is_favorite)
time_range = TimeRange.new(start_hour: start_hour, end_hour: end_hour,
favorite: is_favorite, stream_request_id: id)
time_range.save!
time_ranges << time_range
end
I ran each an every line of code in debugging and it did not gave me this error This error occurs when the request got completed
I am just creating the stream along with a request whose code is listed and that is it. Nothing else
I don't see anything wrong, but there's a lot going on. I would delete everything to start in the API body, make sure that works, then slowly re-add parts of the code to narrow it down.
Sure thank you I will wait for that.
Sorry, I meant you should do that. I will wait to hear what you find.
Weirdly enough, I have a model called Stream too and this is happening to me, sharing none of the above code. @Bilal-Abbas-Gigalabs did you manage to solve it? @dblock perhaps?
Hi, I also encountered the same error.
In my case, it was because I had defined @stream
in my code.
In such a situation,
-
def stream
returns Overwritten@stream
, -
@stream
is stored in response_object. -
bodies is Overwritten
@stream
and the title error occurs.
I hope this helps. Thank you.