many to many relationship crud
It retrieves all the addresses because you query the address from the user himself not from the case object that you supposedly created from the new
view.
So, first, I would add create
action to create the case first (to which we will assign the chosen address):
def create
# @user can be retrieved from the passed id in the url
@user = User.last
@case = Case.create(user: @user)
@case.addresses << Address.where(id: params.require(:case)[:address_ids])
end
and change your controller show
action to something like this:
def show
# @case can be retrieved any way you like, this is just an example
@case = Case.last
end
and make your show
view like this:
<strong>Address: </strong>
<% @case.addresses.each do |s| %>
<%= s.name %>
<% end %>
This would solve your issue.
Some notes to consider later:
- So far this
new
view only allows you to choose one address (not multiple) so it won't be needed to usehas_many
association (if you want to use it, then you have to figure out a way to choose multiple addresses). - The @user.id can be passed through the url instead of explicitly defining it in the form. Look at Nested Resources for more info.
- The
url
attribute in the form can be replaced by _path helpers, the same above link would give you a hint as well. - Try to stick to Ruby styling, like indentation and naming. For example, the |s| is not descriptive .. would be better to be named address or addr
- As I can see, you can try using
through
instead of duplicating the associations. E.g. Case belongs_to User & Case has_many Addresses, so User can has_many cases & User has_many addresses, through: :cases .. like this you can retrieve user's addresses specific to that case. Like this, when you try to create an address and retrieve it from @user.addresses, you will get an error because an address already needs a user and a case to be created in the first place, so the associations are not set perfectly and as a result you will need workarounds to prevent these errors.
STI routing error
You can organize your controller better to avoid this issue altogether. See below
routes.rb
resources :kids
resources :parents
This would directly give you named path:
edit_kid_path(kid_id)
edit_parent_path(parent_id)
kids_controller.rb
class KidsController < ApplicationController
def update
end
end
parents_controller.rb
class ParentsController < ApplicationController
def update
end
end
If you want to share controller behavior, You can potentially do
class KidsController < UsersController
end
class ParentsController < UsersController
end
and put the common actions in users_controller.rb and override them in the child controllers.
The decision on what model relationships to use should be independent of how you structure your controllers. Controllers and routing is one area of consideration. Modeling data is entirely separately consideration. And declaring resources are just shortcuts for some matching routes.
If you are not going to use users#update etc, declaring resources :users
is unnecessary as you are not using any of the routes that declaration provides.
MVC: How to work with entities with many child entities?
If you wish to use the kinds of paths you provided in your example, then it sounds like you should learn how to use the Routing engine in .NET 3.5. You should be able to use the kinds of urls you need, but you will need to create several custom routes and probably a custom route handler to accomplish it. The Routing engine in .NET 3.5 is very flexible and was not designed specifically for MVC...its actually very generic and can provide a very broad, probably unlimited range of url rewriting.
Its a bit late where I live, so the example I was trying to write just isn't forming. :P Suffice to say, a custom route handler and some new route mappings should get you where you need to be.
EDIT: This may be of help:
http://codingcockerel.co.uk/2008/05/26/custom-routing-for-asp-net-mvc/
EDIT 2:
I left out controllers before. The routing just gets you the ability to use the kinds of URLs you want. And thats a good thing...the kinds of URL's you proposed will provide a better SEO experience long-term. As for organizing your controllers, I recommend keeping it simple:
/Controllers/CarsController.cs
/Controllers/PartsController.cs
/Controllers/EmployeesController.cs
/Controllers/InventoryController.cs
Your routes would match your url patterns, and turn them into a proper route to your controller, taking the ID's and matching them to the parameters of your actions.
EDIT 3:
So, now that I understand your question more fully, I hope I can answer it better. Generally speaking, I think controllers should map 1:1 with your entities. If you have a GeneralPart, then you should have a controller dedicated to managing general parts. If you have CarPart, then you should have a controller dedicated to managing car parts. If CarParts are GeneralParts, and they can behave like GeneralParts in some cases, then it is probably best to have those management aspects on the GeneralPartsController, unless that management deals with any special attributes of a CarPart...in which case management should be delegated to CarPartsController. It is kind of elegant how polymorphism plays into controller organization, and how the "is a" relationship allows you to reuse controllers to manage multiple types.
To be honest, you have a fairly complex scenario I havn't directly encountered in my time working with ASP.NET MVC. I try to avoid such scenarios as much as possible, because they give rise to complicated questions like this that tend to be subjective in their answers. Ultimately, you should organize your controllers in a way that makes logical sense to how they are used, how they map to your entities, and how well they organize the behavior you are interested in exposing. Sometimes, it isn't logical to map all of your controllers to a single entity. Sometimes you need to have a "composite" controller that deals with actions that operate on multiple entities at once, or graphs of entities. In these cases, its probably best to have controllers dedicated to those particular behavioral groups, rather than trying to find one entity-specific controller that "sorta fits".
Comments on multiple models
You don't want to specify each type of object that can hold Comment
objects. That creates a headache of if-elsif-else
blocks all over the place. Instead, you want things to be Commentable
, and they all will have .comments
on them.
This is called a polymorphic association in Active Record. So you would have your models something like:
class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true
end
class Post < ActiveRecord::Base
has_many :comments, as: :commentable
end
class Book < ActiveRecord::Base
has_many :comments, as: :commentable
end
And modify your database accordingly, it's all in the linked article. Now when you build a Comment
object for a form, it will have pre-populated a commentable_id
and commentable_type
, which you can toss in hidden fields. Now it doesn't matter what the Comment
is associated with, you always treat it the same.
I'd leave User
as a separate association, since it's not really the same idea.
Rails 4 nested forms link_to edit not working in loop
I think the issue's actually a little trickier, because edit_todo_list_path(list)
seems to throw the same error.
What's going on is that the @todo_lists
variable (first an array of persisted lists) is altered when you run @todo_list = current_user.todo_lists.new
. That command actually adds a new (unpersisted) list to the end of the @todo_lists
array (seems like buggy behavior to me, but it's happened to me before), so that when your view is looping through them, the last one has no id, and a path cannot be created for it.
The solution is (I think) to make that variable after you've used the @todo_lists
variable.
Take @todo_list
out of the controller, and where you use it in the view, instead do current_user.todo_lists.build
. That should instantiate a new list without changing the @todo_lists
variable.
Related Topics
PDF Generation Hangs Using PDFkit and Wkhtmotopdf
How to Get Order Username and Provisiondate for All Softlayer MAChines Using Ruby
How to Convert Timestamp with Ruby
Convert This Xml Request to a Proper Savon Request
Regex to Remove the Webpage Part of a Url in Ruby
Ruby, No Implicit Conversion of Symbol into Integer
How to Set Up These Crud Controller Actions for Has_Many_Polymorphs and an Error
Invalid Route Name, Already in Use: 'Admin_Root' (Argumenterror) - Failed Activeadmin Install
Emulating Int64 Overflows in Ruby
Ruby Before_Validation Triggers Infinite Loop of Call Back
How to Give a Date a Background Color with Axlsx
Receving the Undefined Method 'Generators' Error
How to Multiply "5X3" String in Ruby
How to Mimic Browser X509 Client Certificate Verification Without Access to Http Layer