I'm building an online store and thought it best to namespace the various composite parts. Products, Orders, Users etc...
I currently have the Product Module defined and laid out as follows
Product::Base
The underlying product itself it defines dimensions, a type and available colours
Product::Type
High level product categorisation
Product::Colour
HABTM colour relationship with Base
Product::Unit
Expands on base for varying quantities and shipping prices
Now my question relates to the controller and routing. I want the module to appear as the resource and have one of the models (base) as sort of the "head". I've managed to get this working with
scope :module => "product" do
resources :base, path: "product"
end
which yields from rake routes
base_index GET /product(.:format) product/base#index
POST /product(.:format) product/base#create
new_base GET /product/new(.:format) product/base#new
edit_base GET /product/:id/edit(.:format) product/base#edit
base GET /product/:id(.:format) product/base#show
PUT /product/:id(.:format) product/base#update
DELETE /product/:id(.:format) product/base#destroy
This is exactly the behaviour I want but my question is, is this approach RESTful and correct? I'd rather be told now I've got it wrong than further down the line.
Thanks as ever.
That is RESTful, yes, but try this too:
Blah::Application.routes.draw do
namespace :product do
resource :base
end
end
Gives you:
product_base POST /product/base(.:format) product/bases#create
new_product_base GET /product/base/new(.:format) product/bases#new
edit_product_base GET /product/base/edit(.:format) product/bases#edit
GET /product/base(.:format) product/bases#show
PUT /product/base(.:format) product/bases#update
DELETE /product/base(.:format) product/bases#destroy
Related
What is the correct way to make this api 'restful'
I have a location,
GET location/:id
PUT location/:id
The spec has changed and now this location can have certain 'types' the client can update. One requirement is that the client get the allowed types (could be one of these from a fixed list - i.e.['urban', 'wilderness', 'private', etc..]) for all locations. This isn't a nested resource, its a column on the location table. I've implemented,
GET location/types_allowed
is there are better RESTFUL way?
Another example, a location can have neighbors, so I made GET locations/neighbors. I'm having trouble understanding the nuances of REST beyond CRUD and nested resources. Thanks!
Instead of a column as types_allowed, create a type resource and the relation can be like
location.rb
belongs_to :type
type.rb
has_many :locations
and with this your route file would be
resources :type do
resources :location
end
I strongly recommend against naming a model/column "type". That tends to break magic things inside of rails that you don't even know are there until you try that. It's one of those "undocumented features" :P
I'd instead recommend reading up on "single table inheritance" or "polymorphism" to figure out if either of these is right for you.
If not... then name something "kind" instead of "type" as it'll all work a lot better that way.
As to RESTful resources... you really can't go past the Rails Guides. If you follow the routing guide: (and all the other ones) you'll get an idea of how to do RESTful resources
I have user model and boat model. User has many boats. Boat belongs to user. What i wonder is that, even though i did not nest the resources i am able to create a boat to logged in user. So my url becomes ..../boats.new2 (2 as user id) and it actually saves to user with an id number 2.
But as far as i know if i have nested resources it would become something like .../user/2/boats/1. Isn't it?.
I have not tried to #edit action any of the cases so not sure which one to use and their effects, is there any other advantages using any of them, or not nesting is wrong?
Nesting routes is not necessary in Rails. You can maintain the relationship between boats and users as long as you have the active record belongs_to and has_many methods defined in the model, along with the foreign keys in the db.
In general, you should nest resources if there is an obvious relationship between the objects, such as users and posts (or boats). It just makes more sense of your users and as an API structure.
In some cases, you might want to nest the relationship under something different, like a category name. For instance, your uri pattern could look like /sailboats/boats/1 or powerboats/boat/2. Bottom line is you should structure routes in a way that logical for the project's users and developers.
I have a project going on right now that is really big data model wise. I am trying to figure out the best way to handle inter-model relationships.
For the sake of brevity:
Car
has_many :passengers
has_many :items
or
Team
has_one :head_coach
has_many :coaches
has_many :players
belongs_to :owner
So from the show page I would see who is in the car and what items are in the car. I have some co-workers who think we should have a controller action called manage where they would click a link on the show page to manage the relationship between the other models
So the Team controller would have this
class TeamController < ApplicationController
# ... magic ...
def manage_players
#signed_players = Player.signed_players
#free_agents = Player.free_agents
end
end
The manage_players view would just have links to the actual RESTful actions on the appropriate controller to remove relationships etc...
Anyone have thoughts on how this should be accomplished?
That's an overly complicated approach, and the good news is, it's way simpler than you think.
Save yourself some trouble. The quick answer to your question is to use nested resources: you can have a single form that handles the Car and all the associated passengers/items, or the Team and its coach, players, etc.
The action/view you're describing would just be the edit action on the Car/Team. The manage action name is a nice idea and all, but the action you're really taking is an edit (nothing special, by what you're describing), so why confuse what's going on when the default is to call it edit?
If you want a live example of something that takes advantage of nested routes, check out rpglogger.com (it's my site). When you play around with it, notice the routes/URLs in the address bar.
It's also open source. Specifically relevant to your question is:
see the routes.rb file, and note how I define resources on sections twice - this actually gives me two different versions of the routes - one that's scoped to the LogBook, and one that's scoped to the objects in a section
see the world_object_form.haml (haml also rocks, FYI), which is both my new and edit form - yet it's short, rather uncomplicated, and pretty easy to read/undestand given what it does.
My (rails 3) application use collection and product as models. collection has_many products and product belongs_to collection.
I managed to have interactions between products and models. I created a menu displaying the different collection. I want to display a view showing only the product belonging to a specific collection.
1) Is it more elegant to create a new view/controller, or do i create a new view in the product views
2)It seems that i must do something with the routes.rb, but how and what?
3)What link_to arguments must i use to pass the value of my collection?
4)I read a whole book (pragmatic ROR) and depspite that and doing a lot of online research i keep ending here asking for not so much complicated Rails question. What am i doing wrong?
I would go with creating new action in collection controllers. Url will look like this:
/collections/1/products
where 1 is collection id.
I assume you have
resources collections
so you need to add 'products' action for collection member:
resources collections do
member do
get :products
end
end
You can run rake routes from console to see how your application routes look now.
Link code should look like this
link_to "Collection products", products_collection_path(#collection)
In my opinion reading is ok, but while you read you should do lots of examples, write them yourself, becouse otherwise you forget stuff very quickly. I'm 100% sure that stuff I wrote above was in the book you've read.
Ok, so I've got a weird pattern here that I can't figure out.
I have an STI set with CallList as the base model, and City & State inherited. A city belongs to a state (and a state has many cities).
A campaign has many call lists, so I want to display them all. I loop over campaign.call_lists and sometimes get Cities, sometimes States. When I want to link to them I do
link_to call_list.name, call_list
which works fine if I have these routes:
resources :cities, :states
When I nest cities inside states, however, the link_to helper can't figure out the appropriate route. Is there a simple way to do this, or am I going to have to do some manual path helper construction?
you need to check for kind of call_list and then use proper route..it can not be directly as route is nested..
link_to call_list.name, call_list.is_a?(City) ? call_list : state_city_path(call_list)