Why does Rails use plurals for new and create? - ruby-on-rails

I understand why a Rails index method would use the plural form of a resource - we're showing all projects, for example.
And I understand why the show method would use the singular form - we only want to see one project, with a particular ID.
But I don't understand why new and create would use the plural. Is there a way to create more than one project at a time? Is there some other reasoning for using the plural here that someone could explain?

New and Create aren't plural, in the way I think about REST. Instead, I think about it like:
whatever.com is your base domain, and whatever.com/books means that you have a collection of resources each named book. The collection itself is named books.
So, when you want to create a new book, you are asking the collection for the information needed to create a new book. This becomes /books/new
When you actually create the book, you are posting information to /books. The HTTP verb is POST, so when you POST to your collection, you execute the create action.
This looks like a good starting point on REST.

I thought they were always plural. Scroll down a bit on this page for an example of the routes generated by resources :photos
Whether you're GETting a single resource or POSTing to the collection, you're still in the domain of photos. So, search the domain of photos given an id, POST a new photo to the domain of photos, etc.

Related

Generating the URL of a nested resource without its parent (without using shallow)

In our application, many resources are nested under a common resource representing an organization. Most URLs include an organization ID the following pattern: /:organization_id/notifications/:id.
My problem is that I always have to give the current organization to generate the URL to any model. For example, the link to an existing notification would be link_to [#organization, #notification].
Since a notification already belongs to an organization, I was wondering if it was possible to generate my URL using link_to #notification and it would actually generate a URL including the organization ID of the notification. I was hoping that a configuration in the model would be able to achieve this but I could not find anything in the guides, the docs or the source code of Rails.
I would like to keep the organization ID visible in the URL as this is an information that is used by our customers. So I do not want to use shallow nested resources for this problem.
We are using Rails 5.2.0.
You want the resolve route definition method.
It is designed to do exactly what you want: configure a different behaviour when a single model instance is passed to url_for (as link_to does, for example).
Specifically, in your config/routes.rb, something like:
resolve("Notification") do |note|
[:notification_organization, note.organization, note]
end
It sounds like you were on the right track -- it's just a routing concern rather than a model one.

REST API for custom action other than PUT/POST/GET

I am writing a REST API that basically gives two resources: Users and Cars. With the API, you can POST/GET each resource.
But now I have a custom action that will basically give a new car to a user. This will require a cron job in the back end and do the operation. It doesn't fit the model of POST/PUT. I am just wondering what's the best route for this?
I thought of:
/addNewCarToUser/:user_id
I know this question is too localized but I am just wondering if it's just a judgment call or if there's a convention for this type of request?
Thanks
It depends. Do cars only exist if they belong to users? Or can they exist on their own?
If they are only in the context of belonging to a User, I would just have Cars belong to Users and have a route like this to create a new one:
POST /users/:id/cars
Or you can specify who the owner by a car has_one owner (seems counterintuitive, but data-wise a car often has 0 or 1 owner). The route could be:
POST /cars?user_id=######
Another sensible relation would be to have a third resource Ownerships, and then you could create a new car and then a new ownership, because creating a car and giving it to a user would be 2 new resources.
POST /cars
POST /ownerships
Well, "addNewCarToUser" is an action an therefore it breaches the resource principal.
I could think of
/user/:user_id/cars
This would be the resource to GET or POST.
I would perform a POST since this action will result in the creation of new data.
Not sure what naming convention you're using, but I would do something like this:
/users/:id/new_car # via POST

Opinions on RESTful route for DELETEing of nested resources?

Given a typical nested resource of a photo with comments, the route to create a comment would look something like:
POST /photos/{photo_id}/comments
Now, for deleting the comment, would you still use a "nested" route? ex:
DELETE /photos/{photo_id}/comments/{comment_id}
or
DELETE /comments/{comment_id}
The pro of the nested route is that it mirrors the creation URL and doesn't require any additional entries in routes.rb. The pro of using a top-level URL is that you technically don't need the photo_id to get the comment to delete.
Thoughts?
How you model the comments resource depends heavily how you see the resource comments.
In case a comment could exist without a photo and could be associated with 0 to N resources like photo then you should model your comments like this
GET /comments/{comment_id}
DELETE /comments/{comment_id}
PUT /comments/
POST /comments/{comment_id}/associations/photo/{photo_id}
In case a comment is always associated with a resource and cannot exist without being associated with a resource then you should stick with
POST /photos/{photo_id}/comments
DELETE /photos/{photo_id}/comments/{comment_id}
I guess the confusion how to model the comment is driven by the database model where every comment gets a unique id that is unique among all comments and not just unique in a photo_id and comment_id combined key. I suggest not to let the database model leak to the resource model and go for a model that fits your conceptional understanding of the resource.
Can you GET this?
GET /comments/{comment_id}
I guess not. But if you can't GET a resource, you can't DELETE it, too.
So only your second option is RESTful.
Personally, I'm just using nested route for delete, means i used:
DELETE /photos/{photo_id}/comments/{comment_id}
to delete comments of a photo. If i use:
DELETE /comments/{comment_id}
so i have to create one more route for this? I don't find any reasons to create a separate route for delete, I think it's not necessary. The nested resources have create url and path for us, and they are follow convention, why don't we use them? I just want to keep it simple and will not do extra work for things already have.

Ruby on Rails - enquiring about passing parameters

I am creating a simple RoR application where I can create posts and also comment on them. My thought on how to do this is to have posts and comments be of the same type and utilizing the same MVC except comments have a parent id. Posts will have a parent id of 0 while comments will have the id of its parents. I was thinking of when I tried to create a comment, I could just pass in the parent's id to the new method. This did not work. Although I got no errors it seems like the #post variable in the new method is not the same #post variable in the create method. My intuition was that the new method creates a new object then passes the object to the view. The view then populates the objects parameters and then sends it to the create method and the create method saves the object to the database. From trial and error this does not seem to be the case unless I am just doing it wrong. Is there an easier way to get the same functionality I am trying to achieve? or is there a way to get my way to work? any help would be greatly appreciated!
I would recommend you follow the classic "Build a Blog in 15 minutes" video that shows you how to do this.
Among other things, since a post has_many :comments I wouldn't recommend doing what you're proposing.

What is a "resource" in Rails?

Dumb question but I have some lingering confusion of what, exactly, a "resource" is in Rails. The term is used everywhere but I get a funny feeling it might be being used rather loosely. It's referenced in the model, the controller and, quite literally, in routes.rb.
Is it the specific route? For example, map.resources maps the 7 RESTful "resources". So an example of one resource would be the call to, say, the index action of a particular class's controller?!?
Is it a reference to the whole page/object being retrieved? or perhaps, more narrowly, a database table? or the row being retreived?
Is it something else?
Anyway, hopefully someone can set me straight...
Any object that you want users to be able to access via URI and perform CRUD (or some subset thereof) operations on can be thought of as a resource. In the Rails sense, it is generally a database table which is represented by a model, and acted on through a controller.
For example, you might have a User resource (with a users table in your DB). This is represented by a User model, is mapped to users_controller with map.resources :users (which then generates routes like /users (a collection of User resources) and /users/1 (a specific User resource).
You act upon those resources by using the appropriate HTTP method when making calls to those resources. POST to the resource collection (/users) creates a new record; GET retrieves a list of resources (/users) or a specific user (/users/1). PUT updates a specific user (/users/1/), and DELETE destroys that user. The URLs are the same, but the result (and controller action) may be different based on the HTTP verb. The idea, though is that /users/1 always means "I'm interacting with the User that has ID #1", regardless of the action.
Here's a good article discussing how most developers think that "Resource" is synonomous with the database table, the argument, I guess, being that mapping to the resource is mapping the controller to that database table (or, with ActiveResource, to another REST url).
Basically, I think a "resource" is "persisted data." map.resources maps the 7 RESTful actions to a particular suite of persisted data.
But I haven't thought about it too much in depth. Good question!
I think they probably mean it in the general web sense, i.e., Resource (Web):
the referent of any Uniform Resource Identifier
I don't think it has anything to do with database tables.
open your model folder, that is a hint of what resources you have!
example: users, pictures, comments...
A lot of people here say that resources refer to the database tables you have. It might be true sometimes but not necessarily true always. I could give you a lot of examples where you don't have a corresponding table in your database for a particular resource. Hence asssociating it with tables is rather wrong.
I would define a resource as a route which maps to related requests. So instead of declaring separate routes for the actions you want to do you can simply declare them using a resourceful route.In Rails, a resourceful route provides a mapping between HTTP requests and URLs to controller actions.
So say you define resources :users in config/routes.rb. You can now use a number of helpers to the controllers in your application like edit_user_path which returns users/edit .
Here's a good link: https://api.rubyonrails.org/v5.2.1/classes/ActionDispatch/Routing/Mapper/Resources.html
Which basically says: Resource routing allows you to quickly declare all of the common routes for a given resourceful controller. Instead of declaring separate routes for your index, show, new, edit, create, update and destroy actions, a resourceful route declares them in a single line of code:
resources :photos

Resources