RESTful Actions Best Practices - ruby-on-rails

I've got a RESTful User model working well in Rails 3. I'd like to add a new option to create a new user based on information queried out of a LDAP server.
What I'd like advice on is how best to do this. Here's what I've thought up so far, but I don't know if it matches Rails best practices:
Edit the resource path of User to accept both GET and POST to a new view called "import_ldap_user".
Import LDAP user then presents a form which uses AJAX (POSTing to import_ldap_user) to allow the visitor to search for a person in LDAP. The results are displayed on the page and if acceptable, the user clicks "Create", which then calls /user/create.
Part of why this seems bad to me is:
I need to post a proper #user to /user/create, but I'm not sure if my AJAX call can produce a proper #user.
I don't know if it's a bad practice to add a new verb to the RESTful Users route.
I don't know if using an AJAX POST to import_ldap_users is a proper separation of concerns.
Any ideas? Any Rails perfectionists have opinions about how this should work?

What gets posted to /user/create isn't an #user object but rather its attributes. A scaffolded create action will probably have something akin to #user.new(params[:user]), which just pulls the user attributes that were posted and creates a new object based on that.
Even if your AJAX call doesn't provide the attributes in a manner that can be processed by the new method, you can simply modify your create such that it manipulates the post data.
As for best practices, this is definitely something I've thought about in the past but I don't know if there's a "correct" answer. I think having a new view which posts to the create method is perfectly acceptable, you could also create a new controller if you want to strictly follow the CRUD pattern.
Definitely a good question and if anyone has a better answer I'd love to hear it.

Related

Rails: should I create a new controller when I need actions similar to new, update, destroy?

I found this but it didn't answer my question.
Say I have a Payment model, and PaymentConroller. I have the ability to create one payment, edit it, update etc...
I also have a method payment_wizard. This method spreads payment according to parameters given in 'payment_wizard' form.
But, I want a clean form when I spread new payments, to be able to update an existing collection of payments, and destroy all of them at once.
This is making me think that the "right" thing to do would be to create a new controller PaymentWizardController which does all that.
Is this the right way to do this?
The best approach in my opinion is to keep all your controllers RESTful. Managing a collection of payments could be done by creating a PaymentCollectionController (or however you call it) with update and destroy actions.
Just as is mentined in the question you linked, you don't need a model for every controller you have. Keeping them RESTful is following a convention which makes your code more readable for other users.
Think about controller as a handler of actions which are available for user to visit on your site. Do you really need this payment_wizard controller? Try to create some functions in service for PaymenController to keep it slim.

Accessing POST params in routes.rb

I have a system with a web UI that works as normal, and an API endpoint at /receiver_api. Users send emails which are parsed by Mailgun, who then submit a POST to this endpoint. There are a lot of possible actions that we may want to take, depending on the values of these params (create new post, create new reply, add subscription, delete subscription etc.), and when writing the handler it felt like we were doing a kind of routing again!
So we would like to choose the controller that we direct the request to based on what the POST params are. We are directing /receiver_api to a ReceiverApi#receiver controller/method at the moment, which inherits from ApplicationController. It currently effectively routes requests to other "fake" controllers that don't inherit from ApplicationController (since redirecting from one Rails controller to another wouldn't work). We would like to be ultimately routing to Rails controllers so we can use before_filter and all the other magic in them.
Anyway, one possibility that springs to mind is a method in routes.rb that accesses the POST params and returns the Rails controller/method that should be directed to. 2 questions:
Is this possible? Can you access POST params in routes.rb?
Is there a better way of doing this? We had thought about moving up a level into Rack, and will probably do this at some point, but would rather just get something out of the door if this will take a while.
Thanks!
Choosing a controller based on params is not a good thing to do.
A better alternative is to refactor your code (in those fake controllers) to methods in your model, and call model methods based on the params from your controller.
You cannot access params in your routes.rb, because it is run at initialization.
If you really want to call controllers based on params, there is a way of doing this, by redirecting to another controller. This is explained in http://www.railsonwave.com/2008/10/25/how-to-call-a-controller-s-action-from-a-different-controller/ [bad link], but do note that it is very much a hack.

Rails - What is right way to do a show page for a nested resource

since I am only going to be showing that one item, do I just have (example)
/the_thing/23
or do I still go with the /the_group/1/the_thing/23
I know I need to appropriately nest and have associations for forms and using nested routes for links, but for a show page is my link to it nested or not?
i.e. should I still show it within the context of its master or just on it's own. In this case the resource cannot be updated without the nesting i.e. on it's own.
Will a main intent be to show links back to the group?
This question is ONLY about the show page.
This is just a matter of choice, you can even create both routes depending on the context.
You should just ask yourself if it makes more sense for the user to see one url or the other: it's sheer user experience here.
It's true that it's only a matter of choice.
But consider a case, you have a Post model and Comment model, and Comment is a nested resource of Post. It does not make sense to have a separate route for show action of Comment, as showing comments without the relevant post makes no sense.
Hence, it's case specific as well.

Better solution than accessing routes in the Model?

So I know that you shouldn't use UrlWriter methods in a model, but I wasn't sure what a better way to handle my current situation is.
Basically, I want to allow a User to post something to his facebook feed, and want to write a post_to_fb_feed(object) method in class User. Now, the URL of what is actually posted depends on the object, so I also have a to_fb_feed_item method on the object classes that a user can post. The to_fb_feed_item method just returns a hash that the Facebook API expects, including the url the post should link to.
I've gotten this to work currently, by including ActionController:UrlWriter in my models, but I was wondering if anybody had a better suggestion for how to handle this.
Thanks!
Eric
including ActionController:UrlWriter is the best way to handle it. I don't know why it's not easier to generate urls from arbitrary places in Rails -- sure it might be more common for the appropriate place to be in controllers and views, but the fact of the matter is many models validly deal with urls as data, and need to generate them.

Ruby on Rails - Create Entity with Relationship

I'm new to rails, so be nice.
I'm building a "rolodex" type application, and this question is about the best way to handle creating an entity along with several relationship entities at the same time.
For (a contrived) example:
My application will have a Person model, which has_one Contact_Info model. On the create.html.erb page for Person it makes sense for the user of my appliction to create the person, and the contact_info at the same time.
It doesn't seem right to include details for creating a contact directly in the create view/controller for person. What's the rails way to handle this?
Using nested attributes is the most common way to do this.
The actual documentation is here.
You want to use "Nested Forms". There is a great example of them in this blog post.
I'm also noob, but I had a similar issue with an app. I was using a tutor at the time and he basically said it was a good example of rails being opinionated. It sounds like you want to take the create action for two different models at the same time, which may be possible but probably very hard. Id suggest considering whether your data model could be modified, or find a way to make an acceptable user flow while collecting the data in different forms.
Update: while writing this the technical answer came in. Keep in mind, its perfectly okay to take the easy route if doing so helps you get the app out the door, and especially while you're still new.

Resources