Making rails-api (rails 4.0.2/9) work with strong parameters.

Hi All!

I have been trying just about everything I can find on the web to make rails-api work with strong_parameters but no matter what I do, I get the following error:

NoMethodError (undefined method `permit' for "{email: xxx@xxx.org, password: xxxxxxxxx}":String):

All of the answers I have found give ways to add StrongParameters to ApplicationController::Api, but none of them change the resulting error. Debug printouts show that the recommended changes are being executed. I generated a test app using rails without -api and it works fine, but is much bigger due to all of the non-api cruft.

I am using both rails 4.0.2 and 4.0.9 (can't use higher versions due to some old but necessary gems).

Any help would be appreciated.

Thanks,

Don Ziesig

Your payload looks like a string, is permit something you can call on a string object?

Unfortunately, no. That is exactly the problem. The expression params.require(:user) (for example) returns a string in rails-api and an object which has .permit as a method in just plain rails. All of the "solutions" try to change the controller from one derived from ::Api (does not support strong parameters) to one derived from ::Base (which does support strong parameters). :cry: .

Unfortunately, no. That is exactly the problem. The expression
params.require(:user) (for example) returns a string in rails-api and an
object which has .permit as a method in just plain rails. All of the
“solutions” try to change the controller from one derived from ::Api
(does not support strong parameters) to one derived from ::Base (which
does support strong parameters). :’( .

Do you know why the payload is a string rather than a hash ?What format is the data being posted in (form data,json, xml etc ?) It seems to me that your first problem is to solve this - even if you were to solve the strong parameters bit presumably your code is expecting params[:user] to be a hash

Fred

Hi Fred,

I am using rails-api because I am doing all interactions with the rails app in json. Using rails-api eliminates all of the rendering code and keeps heroku happy from a memory usage point of view.

From one of the many posts I found discussing this problem (this one from StackOverflow):

The error above comes from the|require()| <https://github.com/rails/rails/blob/master/activesupport/lib/active_support/dependencies.rb#L225>method in>ActiveSupport::Dependencies::Loadable|being executed when calling

params.require(:user)...|

strong_parameters|injects|ActionController::StrongParameters|into|ActionController::Base|at

the bottom ofthis file <https://github.com/rails/strong_parameters/blob/master/lib/action_controller/parameters.rb#L148>with

ActionController::Base.send:include, ActionController::StrongParameters|

The>rails-api|gem requires your app's|ApplicationController|extend|ActionController::API|in favor of>ActionController::Base|

The application controllers don't know anything about>ActionController::StrongParameters|because they're not extending the class|ActionController::StrongParameters|was included within. This is why the|require()|method call is not calling the implementation in>ActionController::StrongParameters|.

To tell>ActionController::API|about|ActionController::StrongParameters|is as simple as adding the following to a file in|config/initializers|.

ActionController::API.send:include, ActionController::StrongParameters|

This is one of the many "solutions" I tried that doesn't work for me. :cry:

Thanks,

Don

Hi Fred,

I am using rails-api because I am doing all interactions with the rails
app in json. Using rails-api eliminates all of the rendering code and
keeps heroku happy from a memory usage point of view.

Does the above answer Fred's questions?

If you post your reply after the questions it may be easier for us to see
exactly part of the previous post you are replying to.

Colin

The payload is a string because the app was generated using rather than . I am using because I am doing all interactions with the rails app in json.
Using eliminates all of the rendering code and
keeps heroku happier from a memory usage point of view.
When I generate the exact same app using just plain it responds correctly to the incoming json with its own
json results. In other words, returns an which responds to the method with but
the same code returns a with ,
raising the exception.
I have found many “solutions” to this on the web (so I am not the
first to encounter it), but for some reason none of them work for
me. The explanation below gives more technical details (this one
came from StackOverflow):
In order to get some productive work done, I am currently
implementing the code using but the more I
do, the more I will have to re-do before deployment, or I will have
to remove the unused code manually later.
Thanks,
Don

I still think you have a more fundamental problem. With or without strong_parameters, params[:user] should be a hash (and the rails-api gem looks like it loads strong parameters for you anyway). How are you making your post requests to your app?

Fred

Hi Fred,
I am using two sources for the requests. The eventual production
source is a Single Page App I am writing in ember.js. The testing
source is Google Chrome’s Postmaster which gives me total control
over what is sent. Both send json posts. When I am running a plain
app both work exactly as expected. When I am running ,
both fail in exactly the same way.
For additional background, the new app is a replacement for an
existing rails app that works well on high speed internet links, but
is difficult to use on (relatively) slow internet links such as 4G
cellular due to too many round trips to the server with too much
data coming back for each rendering, even after much optimization. Also, as I mentioned before, because of some old gems I am limited
to using 4.0.2 and 4.0.9. Your question made me
realize that I haven’t tried 4.2.3 without the old
gems. I will try a test app running the latest version of and see if anything changes. I might be fighting a problem that has
been solved in the most recent versions. If so, I have a totally
different issue: how to get the obsolete gems updated. I’ll get back to you (in a few hours).
Thanks,
Don

Hi Fred (and All)!

Your question pointed me in the right direction. The problem is that *rails-api* 4.0.9 and lower do not handle strong parameters alone or with any of the many solutions I found posted on the web. :cry:

I setup a clean rvm gemset, installed *rails* 4.2.3 and *rails-api *4.2.3. I used *ruby* 2.2.2 and *rails-api* 4.2.3 (the latest and greatest releases) to create a test app without my old gems.

The test app responded to the ember SPA and Google Chrome Postman perfectly :sunglasses: . Now I have to see about upgrading or working around the old gems so I can use *rails* 4.2.3. :frowning:

For anyone who might be wondering, I have not tested *rails-api* with versions greater than 4.0.9 and less than 4.2.3 so I don't know exactly where the breakage occurred.

I owe, I owe, so off to work I go :smiley: .

Thanks,

Don