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

222 views
Skip to first unread message

Donald Ziesig

unread,
Jul 24, 2015, 9:32:22 PM7/24/15
to Ruby on Rails: Talk
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: x...@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

BuyzLots

unread,
Jul 24, 2015, 10:10:17 PM7/24/15
to rubyonra...@googlegroups.com
Your payload looks like a string, is permit something you can call on a string object?
> --
> You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-ta...@googlegroups.com.
> To post to this group, send email to rubyonra...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/55B2E6FF.9060607%40ziesig.org.
> For more options, visit https://groups.google.com/d/optout.

Donald Ziesig

unread,
Jul 24, 2015, 11:34:48 PM7/24/15
to rubyonra...@googlegroups.com
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). :'( .

Frederick Cheung

unread,
Jul 25, 2015, 5:16:55 AM7/25/15
to Ruby on Rails: Talk, don...@ziesig.org, don...@ziesig.org


On Saturday, July 25, 2015 at 4:34:48 AM UTC+1, donz wrote:
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

Donald Ziesig

unread,
Jul 25, 2015, 10:23:23 AM7/25/15
to rubyonra...@googlegroups.com
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() method in ActiveSupport::Dependencies::Loadable being executed when calling

params.require(:user)...

strong_parameters injects ActionController::StrongParameters into ActionController::Base at the bottom of this file 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::StrongParametersbecause 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. :'(

Thanks,

Don

Colin Law

unread,
Jul 25, 2015, 10:34:51 AM7/25/15
to rubyonra...@googlegroups.com
On 25 July 2015 at 15:22, Donald Ziesig <don...@ziesig.org> wrote:
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

 

Donald Ziesig

unread,
Jul 25, 2015, 12:46:47 PM7/25/15
to rubyonra...@googlegroups.com
Hi Fred,

Colin Law suggested that I re-order this and make the response a little more direct (thanks, Colin).  Here it is.


On 07/25/2015 05:16 AM, Frederick Cheung wrote:


On Saturday, July 25, 2015 at 4:34:48 AM UTC+1, donz wrote:
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

The payload is a string because the app was generated using rails-api new myapp rather than rails new myapp.  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 happier from a memory usage point of view.

When I generate the exact same app using just plain rails new myapp it responds correctly to the incoming json with its own json results.  In other words, params(:user) returns an object which responds to the permits method with rails but the same code returns a string with rails-api, raising the NoMethod 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):



The error above comes from the require() method in ActiveSupport::Dependencies::Loadable being executed when calling

params.require(:user)...

strong_parameters injects ActionController::StrongParameters into ActionController::Base at the bottom of this file 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::StrongParametersbecause 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

In order to get some productive work done, I am currently implementing the code using rails new ... 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
 
On 07/24/2015 10:09 PM, BuyzLots wrote:
> Your payload looks like a string, is permit something you can call on a string object?
>
>
>
>> On Jul 24, 2015, at 9:31 PM, Donald Ziesig <don...@ziesig.org> wrote:
>>
>> 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: x...@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
>>
>> --
>> You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
>> To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-ta...@googlegroups.com.
>> To post to this group, send email to rubyonra...@googlegroups.com.
>> To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/55B2E6FF.9060607%40ziesig.org.
>> For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-ta...@googlegroups.com.
To post to this group, send email to rubyonra...@googlegroups.com.

Frederick Cheung

unread,
Jul 25, 2015, 1:21:27 PM7/25/15
to Ruby on Rails: Talk, don...@ziesig.org, don...@ziesig.org


On Saturday, July 25, 2015 at 5:46:47 PM UTC+1, donz wrote:
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

The payload is a string because the app was generated using rails-api new myapp rather than rails new myapp.  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 happier from a memory usage point of view.

When I generate the exact same app using just plain rails new myapp it responds correctly to the incoming json with its own json results.  In other words, params(:user) returns an object which responds to the permits method with rails but the same code returns a string with rails-api, raising the NoMethod 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):


 
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 

Donald Ziesig

unread,
Jul 25, 2015, 2:37:42 PM7/25/15
to rubyonra...@googlegroups.com
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 rails app both work exactly as expected.  When I am running rails-api, 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 rails 4.0.2 and 4.0.9.  Your question made me realize that I haven't tried rails-api 4.2.3 without the old gems.  I will try a test app running the latest version of rails-api 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
--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-ta...@googlegroups.com.
To post to this group, send email to rubyonra...@googlegroups.com.

Donald Ziesig

unread,
Jul 25, 2015, 5:45:15 PM7/25/15
to rubyonrails-talk@googlegroups.com >> Ruby on Rails: Talk
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. :'(

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 8-) .  Now I have to see about upgrading or working around the old gems so I can use rails 4.2.3. :-(

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 :-D .

Thanks,

Don
Reply all
Reply to author
Forward
0 new messages