swagger unique operationId means odd-looking code from swagger-js - swagger

Having read up on the specs, I see that each operationId must be unique across the entire spec. I know this is the requirement, but it still seems odd that it's not unique within the path / route.
So, as a result of this uniqueness, if I have a route of SomeLongModelName and a method of someMethod the operationID becomes SomeLongModelName.SomeMethod and the code generated by swagger-js is therefore
SomeLongModelName.SomeLongModelName_SomeMethod().then
which just looks ... horrible ...
Is there anyway of getting swagger-js to generate client methods like
SomeLongModelName.SomeMethod instead ?

Related

URL Structure for Comparing Items

What is the best way to structure a route for comparing multiple items?
Here's the URL example: https://versus.com/en/microsoft-teams-vs-slack-vs-somalia
How to achieve this in routes.rb file? Cannot really find anything in Internet regarding ruby gems. The only thing I can think about is url with optional params, however what if the number of params is unlimited?
you're going to have to parse the a-vs-b-vs-c yourself.
So in routes.rb, you'll have something like:
get 'compare/:compare_string', to 'compare#show'
then you'll get a parameter compare_string that you'll have to parse:
#in compare_controller.rb
def show
compare_items = params[:compare_string].split('-vs-')
# generate the comparison from the compare_items array
end
First - you probably shouldn't allow unlimited #'s of parameters in practice. Even something like 100 might break your page and/or cause performance issues and open you up to DOS attacks. I'd choose some kind of sensible/practical limit and document/enforce it (like 10, 12 or whatever makes sense for your application). At around 2k characters you'll start running into URL-length issues.
Next - is there any flexibility in the URL? Names tend to change so if you want URL's to work over time you'll need to slug-ify each of them (with something like friendly-id) so you can track changes over time. For example - could you use an immutable/unique ID AND human-readable names?
In any case, Rails provides a very flexible system for URL routing. You can read more about the various options / configurations with their Rails routing documentation.
By default a Dynamic Segment supports text like in your example, so (depending on your controller name) you can do something like:
get 'en/:items', to: 'items#compare'
If it's helpful you can add a custom constraint regexp to guarantee that the parameter looks like what you expect (e.g. word-with-dashes-vs-another-vs-something-else)
get 'en/:items', to: 'items#compare', constraints: { items: /(?:(?:[A-Z-]+)vs)+(?:[A-Z-]+)/ }
Then, in your controller, you can parse out the separate strings however you want. Something like...
def compare
items = params[:items].split('-vs-')
end

Unpermitted parameters issue Ruby on Rails 5

I'm currently trying to understand how permitted parameters works in ruby.
Usually, in my_model.rb I have:
has_many: some_other_model
*
*
*
def my_model_params
params.require(:my_model).permit( :column1, some_other_model_attributes %i[other_column1])
etc...
and in the update function
my_object.update_attributes(my_model_params)
with a well formatted json which has some my_model root, and some_other_model_attributes as a child (array) with values.
My problem is I receive a json like this one
However the different arrays inside (such as codification, general_information) do contain attributes of the mission (general_information contains reference that is a column in the mission table) but there isn't any column named codification, or relation to a codification_attributes.
So, when I add :
general_information: %i[reference] in the permitted params, it says unknown attribute 'general_information' for Mission.
If not, no error are raised but in the log I can see unpermitted_parameter: general_information. And my object is not updated.
Finally if I reject it, there is no more unpermitted_parameter: general_information in the log but my object is not updated either.
I tried to set config.action_controller.action_on_unpermitted_parameters to false in my development config, it did nothing and it's probably a bad idea for production environment anyway.
The use of .permit! (even if it works) is currently not an option. And even though I think the json needs to be re-formatted it'd be better to find an other solution.
Thanks for the help.
unpermitted_parameter: ... in logs in not a problem which you need to fix, it's just an info.
How it works - you just permit needed parameters, you may think about them as a hash. Unpermitted parameters will not go into the model even if they are present in params. It means when you call
my_object.update_attributes(my_model_params)
it works like
my_object.update_attributes(column1: value_for_column1_from_params)
Keys in params should be named exactly as columns in the model, otherwise you need to prepare params somehow before create/update

conditional match on rails rspec

I want to write a test on helper method which fetches data from external service based on an id. So there is an uncertainty whether the value will be returned or nil. But if value is returned, id of returned value must be equal to given id. Is there a way to achieve this?
expect(record).to be_nil.or expect(record.id).to eq(deal.user_id)
however it seems the or condition does not work the way I think. I am new to RoR. Might be missing any obvious way to do it.
You can write ruby code in specs too:
if record != nil
expect(record.id).to eq(deal.user_id)
end
or combine matchers:
expect(record).to be_nil.or(eq(deal.user_id))

Rails - trying to understand a piece of code

I am working with some code I found online:
def person_path(options)
# This is where the path of the query is constructed.
path = "/people/" # For this section of the LinkedIn API
if id = options.delete(:id)
path += "id=#{id}"
elsif url = options.delete(:url)
path += "url=#{CGI.escape(url)}"
else
path += "~"
end
end
I am not completely certain what it does. what I am trying to do is have it construct a string something like this: http://api.linkedin.com/v1/people/~:(current-status) which I got from the LinkedIn developer docs here: https://developer.linkedin.com/documents/profile-api
Any thoughts on what I should pass this functions and how exactly it accomplishes what it does?
Thanks!
Whilst it's not stated what 'options' is, it's extremely common to pass in options to a method as a Hash of key-value pairs in Ruby, so I'd say that options is just that (with 99% certainty). This is the part that's key to understanding the rest of the code.
I believe that the #delete method on hash is being used in order to pull out the key-value pair and assign the value in one move, whilst taking advantage of the returned object's "truthiness".
http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-delete
And by "truthiness", I mean that in Ruby, all objects evaluate to 'true' except 'nil' and 'false'.
The rest is simple if-else control flow logic that you will have seen in any other language, so I hope this makes sense.
This just creates a path of the form "/people/id=foo" or "/people/url=foo_with_%_escapes" if it finds id or url in the options. As a side effect, it deletes the one it finds from the options. If it doesn't find either one, it gives "/people/~"

how to parse multivalued field from URL query in Rails

I have a URL of form http://www.example.com?foo=one&foo=two
I want to get an array of values ['one', 'two'] for foo, but params[:foo] only returns the first value.
I know that if I used foo[] instead of foo in the URL, then params[:foo] would give me the desired array.
However, I want to avoid changing the structure of the URL if possible, since its form is provided as a spec to a client application. is there a good way to get all the values without changing the parameter name?
You can use the default Ruby CGI module to parse the query string in a Rails controller like so:
params = CGI.parse(request.query_string)
This will give you what you want, but note that you won't get any of Rails other extensions to query string parsing, such as using HashWithIndifferentAccess, so you will have to us String rather than Symbol keys.
Also, I don't believe you can set params like that with a single line and overwrite the default rails params contents. Depending on how widespread you want this change, you may need to monkey patch or hack the internals a little bit. However the expeditious thing if you wanted a global change would be to put this in a before filter in application.rb and use a new instance var like #raw_params
I like the CGI.parse(request.query_string) solution mentioned in another answer. You could do this to merge the custom parsed query string into params:
params.merge!(CGI.parse(request.query_string).symbolize_keys)

Resources