I have an Active Resource model that needs to set a header before posting/putting through save and update_attributes. The issue is that the header value needs to be different for each user, so it can't be set at the model level. I've seen examples for setting headers as part of a find, get, or custom methods, but no way to add it to a #myclass.save. Something like prefix_options but for headers would be ideal (#myclass.prefix_options[:myvar] = 'abcd') but I haven't found anything like that. Any insight would be appreciated.
I just had a similar problem and overrode .headers on my ActiveResource class. ActiveResource::Base.headers is just a hash by default, but you can override it to be a method! <3 U Ruby.
http://rmosolgo.github.io/blog/2014/02/05/dynamically-generated-headers-for-activeresource-requests/
I just checked in the code for 3.2.8, and it looks like it's not supported. I also don't see much opportunity for monkeypatching it.
https://github.com/rails/rails/blob/c2193c11ad215d3a2d7d35960630b3e1902a5082/activeresource/lib/active_resource/base.rb#L1359
It woud be a great patch to submit though, especially now that activeresource has been split off into its own gem for 4.0.
update
actually you can specify headers with a raw post request. you just can't specify them with the more abstract methods like create:
https://github.com/rails/rails/blob/c2193c11ad215d3a2d7d35960630b3e1902a5082/activeresource/lib/active_resource/connection.rb#L97
Related
I have a URL that looks like this:
http://localhost:3000/activities/5NcsdzWvXbv
I'd like to make it look something like this:
http://localhost:3000/activities/river-rafting
I have a column in my non-activerecord database that stores the names of activities that I'd like to use instead of the id.
I've taken a look at friendly_ID gem but it looks like it won't work for me because of the way my model is set up.
class Leads
include ActiveAttr::Model
end
Is there an easy solution to this?
I checked out an old rails question that recommended doing this:
def to_param
self.name
end
This wouldn't work for me as my model file isn't connected to activerecord but instead an external nosql database.
Can I just make some modifications to my routing file or is there some other way to modify my URL?
Thanks for your time.
I don't quite understand your problem.
If your routes.rb is set up properly, then it will translate to activities/:id. So, if you're preparing data in controller, then it's up to you how you will fetch the data, passing params[:id] to your non-activerecord ORM.
The :id is just a placeholder. If you defined your route as activities/:slug, then you would access the id part using params[:slug]
Can you please post the part of the code which is not working for you?
Edit:
You still haven't posted any code which is not working for you. Anyways, I feel that you need to check some docs on working with multiple databases in Rails. Here is a sketch for starters:
Class YourClass
establish_connection "your_external_database"
end
Then you use that connection to perform queries to the db, using your slugs.
Edit2:
Ahhh... you need to obfuscate ids. It just boils down to exposing encoded ids and then decoding them at your (backend) side :)
Here is an example approach:
How do I obfuscate the ids of my records in rails?
The recommended solution is this:
config.active_record.whitelist_attributes = true
But this only works if you are using active record. On a mongoid rails project is there a similar approach? It uses active model but not active record.
I've never used Mongoid, so this is pretty speculative, but from the looks of it, AR uses a Railtie initializer to set attr_accessible(nil) when that config is true.
It doesn't look like there's currently way to do that in a config, but you could probably hook it somehow with your own initializer. In Mongoid::Fields, if the config for protect_sensitive_fields is true (the default), it calls attr_protected for id, _id, and _type. That also sets the active_authorizer to a blacklist. You could probably patch that up and give a better config for white list that calls attr_accessible(nil) instead.
So yeah, wouldn't be a bad idea to just make a patch then submit a pull request. The last thing the ruby community needs is another high profile mass assignment fiasco.
I have asked the same question
https://groups.google.com/forum/?fromgroups#!topic/mongoid/xuBbuyhiFEU
It is currently not supported but you can do a (straight forward) monkey patch (as Benedikt
suggested)
https://gist.github.com/1977438
It is very similar to AR (you could check in AR code, I copy it here for simplicity)
ActiveSupport.on_load(:active_record) do
if app.config.active_record.delete(:whitelist_attributes)
attr_accessible(nil)
end
app.config.active_record.each do |k,v|
send "#{k}=", v
end
end
This will do the trick for now:
http://groups.google.com/group/mongoid/browse_thread/thread/de5a93a350b49c02?pli=1
So we run a code quality tool called reek once in a while as part of our project. The tool basically looks for code smells and reports them. Here, we observed that we get "Duplication" smell every time we try to access a key in params more than once (As if we are making a method-call twice with same parameters or we are duplicating an if condition etc). However, params is just a Hash, right? Other hashes don't get duplication smell when their keys are accessed more than once.
Why is this so? What are params exactly? Does it make sense to cache params in a local variable then use them? Will it help or its the same? Or is there something wrong with the tool? Help!
With the current version it's best to run Reek only on your app/models folder, because it raises false positives against views and controllers.
params is a kind of DTO (data transfer object) close to the system boundary, and so its characteristics should be different than regular code. But Reek doesn't know that (yet). I plan to improve Reek in the near future so that it plays better with Rails. For now though, your best bet is to restrict it to looking at app/models (and maybe app/helpers and lib).
params is a method call that does a #params ||= #request.params
It might be that it thinks params is a complicated method, so it wants you to try and cache it in a variable, but, dont think that would be worth it especially since it is memoized (based on my rack_process.rb from Rails 2.2)
params[:foo] is a method-call to Hash#[], so reek is correct. I'm not familiar with reek, so I can't tell why other Hash accesses don't get counted the same. Hash#[] should be fast enough that you don't need to store it in a local variable unless you're in a very performance critical part of your code.
The only difference between the params Hash and a regular Hash is that it uses with_indifferent_access, meaning you can access any key with a String or a Symbol.
I believe every time you call params, there is an initialization step which generates method calls, i suppose you can try creating a params and checking number of calls.
this could be blind guess. :-)
I have a Bill model with nested Customer model.
The Customer model has a phone number with a uniqueness validation on it.
While creating the bill I want to fetch the existing record based on the phone number or create a new one if such doesn't exist.
How should I do it in a RESTful way?
you would use the find_or_create_by method which would look something like this in your case:
fetchedRecord = Bill.find_or_create_by_phone_number(customer.phone_number)
You can look at the find_or_create or find_or_create_by methods (which are dynamically created). A little Googling should get you there the rest of the way, I think.
It doesn't seem like these answers are what you are asking.
Forget about Rails, my question would be, what's the RESTful way to create a resource that might already exist? Should you POST to the resources (list) URL, and then expect a HTTP status code of 201 if the resource was created and a 200 if it already existed?
Seems like this should be spelled out in a standard somewhere.
By the way, this is how I am handling it--with status codes.
I place mine in the the association callback before_add
What do you think is the best way to create SEO friendly URLs (dynamically) in Rails?
Override the to_param method in your model classes so that the default numeric ID is replaced with a meaningful string. For example, this very question uses best-permalinking-for-rails in the URL.
Ryan Bates has a Railscast on this topic.
ActiveSupport has a new method in Rails to aid this - String#parameterize. The relevant commit is here; the example given in the commit message is "Donald E. Knuth".parameterize => "donald-e-knuth"
In combination with the to_param override mentioned by John Topley, this makes friendlier URLs much easier.
rsl's stringex is pretty awesome, think of it as permalink_fu done right.
I largely use to_param as suggested by John Topley.
Remember to put indexes such that whatever you're using in to_param is quickly searchable, or you'll end up with a full table scan on each access. (Not a performance-enhancer!)
A quick work-around is to put the ID somewhere in there, in which case ActiveRecord will ignore the rest of it as cruft and just search on the id. This is why you see a lot of Rails sites with URLs like http://example.com/someController/123-a-half-readable-title .
For more detail on this and other SEO observations from my experience with Rails, you may find this page on my site useful.
For me friendly_id works fine, it can generate slugs too, so You don't need to matter about duplicated urls, scopes are also supported.
Check out the permalink_fu plugin (extracted from Mephisto)... the Git repository is located here.
I have made a small and simple gem which makes it easier to override the to_param method. It can be found here.