How to create a view to manage associations between HABTM models? (Rails) - ruby-on-rails

I am using Ruby on Rails and need to create a view that allows the creation of records through a HABTM relationship to another model. Specifically, I have the following models: Customer and ServiceOverride, and a join table customers_serviceoverrides. Using the customer view for create/update, I need to be able to create, update and delete ServiceOverrides and manage the attributes of the associated model(s) from the same view.
Visually I'd prefer to have something like a plus/minus sign to add/delete service overrides, and each serviceoverride record has two string entities which need to be displayed and editable as well. However, if I could just get the code (a kind of nested form, I'm assuming?) working, I could work out the UI aspects.
The models are pretty simple:
class ServiceOverride < ActiveRecord::Base
has_and_belongs_to_many :customers
end
class Customer < ActiveRecord::Base
has_and_belongs_to_many :serviceoverrides
end
The closest thing I've found explaining this online is on this blog but it doesn't really address what I'm trying to do (both manage the linkages to the other model, and edit attributes of that model.
Any help is appreciated. Thanks in advance.
Chris

The ascii cast at http://asciicasts.com/episodes/17-habtm-checkboxes has a simple and functional example.

Related

Rails Nested Form and dependent relationships

I currently have a few models, users, clients, addresses and contacts.
I used scaffold to create my client model which only contains name, leadsource and DBA. It is currently working just fine.
My address and contact was created separately as a client can have many addresses and contacts and they require a client_id to set up the relationship.
Assuming I am using your standard crud operations, is there any way to set up a single nested form that will allow me to add all 3 at once?
Sure, the standard way is fields_for.
But normally you also want to dynamically add and remove associated objects (i.e. addresses) and that's a bit more advanced.
There are gems to help you. i.e. cocoon and a great railscast: episode 403.
Unfortunately it's a pro episode, but investing the $9 is well worth it, as the railscasts really are a source of inspiration (at least for me).
I assume, you already have the associations or create them:
rails generate migration AddClientReferenceToAddress client:references
rake db:migrate
and in models:
class Client < ActiveRecord::Base
has_many :addresses
end
class Address < ActiveRecord::Base
belongs_to :client
end

Rails: Pros and Cons of multiple models

I'm running a Rails 4 app and have a question about how to structure it. My application has users. These users have many fields that can be grouped into categories, such as Personal Info, Work Info, Home, etc.
My question deals with whether I should make separate models for each of these subgroups so users have many has_one associations, or instead just name the fields in the following fashion: personal_info_name, personal_info_address, work_info_address, etc.
Here are some of my thoughts for grouping into models:
Pros:
organization
readibility
Cons:
takes more database space
more models means more files/overhead
Is there a "Rails-way" to do this/what are some other pros/cons for having multiple models?
P.S.
I've read a bit about the "fat model, skinny controller" ideas, but am not sure I entirely understand them (if they pertain to the question).
You should still use proper has_one relations, but utilize ActiveRecord delegates to create shortcut methods:
class User < ActiveRecord::Base
has_one :personal_info, ...
has_one :work_info, ...
delegate :personal_info_name, to: 'personal_info.name'
delegate :personal_info_address, to: 'personal_info.address'
delegate :workd_info_address, to: 'work_info.address'
end
Of course, assuming you are using Active Record as an ORM. Otherwise, you could go the manual route:
class User
attr_accessor :personal_info, :work_info
def personal_info_name
personal_info.name unless personal_info.nil?
end
def personal_info_address
personal_info.address unless personal_info.nil?
end
def work_info_address
work_info.address unless work_info_address.nil?
end
end
OK this is just one of many ways of doing it. I usually create a Profile model, which belongs to a User. One user can either have one Profile, or, if this app is going to grow and allow one User to manage multiple properties, it could have many Profiles later on. Inside these Profiles you can use PGSQL HStore (tutorial here) to store many small preferences (tel1, tel2, address, address_work, etc.) to keep your database from cluttering. Good luck!

In a single form, linking two instances of two models with habtm

I am using Rails 3.
I have a Product model and a Group model (a group has_many users, through membership).
I would like to build the new.html.erb form for the product model, and at the end of the form, I would like the user to be able to choose members from which group(s) can have access to the product he wants to add.
So, my goal is to list the groups to which the user belongs to, adding a checkbox for each of them. Then, create the associations between the product inserted and the different groups the user selected when the form is submitted, but I really do not understand how to achieve this, as all the documentation I have read use the BUILD or CREATE method that defines a new instance of group, instead of an existing one.
Is it possible with a nested form, and a HABTM relationship between product and group ? Or should I use a nested form with a has_many_through association using new model product_group_relationship ? Or should I use something else than a nested form ?
I'm quite new in Rails and a little bit lost here, so if some experienced guy could guide me a little bit, it would be very much appreciated!
The form_for helper comes with a nice package of extra methods like: fields_for wich makes you able to add nested attributes for has_many_through relations.
I suggest reading these:
http://apidock.com/rails/ActionView/Helpers/FormHelper/fields_for
And make sure you set your model validations accordingly

How can I expose a Mongoid embedded collection?

I have mongoid setup in my rails3 app, and have created 2 models.
One model is user, and the other model is article.
Since I each user can create many articles, I have put:
embedded_in :user
in model/article.rb file, and:
embeds_many :articles
in model/user.rb file.
Now, if I access article by 'app_url/articles/random_article_id' I get the following error.
Access to the collection for Article is not allowed since it is an embedded document, please access a collection from the root document.
While I want to maintain relationship, I want articles to be accessible to any people. How can I do that??
It sounds like what you want is a referenced relation rather than an embeds relation for this: http://mongoid.org/docs/relations/referenced.html
also, if you really need to make articles embedded, do this:
User.where("article.id" => params[:id].first.articles.find(params[:id])
but, as Ben said, you would better use belongs_to instead of embedded_in.

How to do a select field in Rails for a many-to-many relationship (and intermediary table)?

Trying to do a select field for an admin interface.
What I have is not a traditional many-to-many relationship, but I imagine the principles are the same. I have an "Event" model and an "EventRelation" model...every Event can have many sub-events, and one primary event...so EventRelation has primary_event_id and sub_event_id fields.
How would I make a select field that would allow me to specify a primary_event for any given Event?
The relevant model code:
class Event 'primary_event_id', :class_name=>'EventRelation'
has_one :primary_event_relation, :foreign_key=>'sub_event_id', :class_name=>'EventRelation'
has_one :primary_event, :through=>:primary_event_relation, :foreign_key=>"primary_event_id"
has_many :sub_events, :through=>:sub_event_relations, :foreign_key=>"sub_event_id"
end
class EventRelation 'Event', :foreign_key=>"primary_event_id"
belongs_to :sub_event, :class_name=>'Event', :foreign_key=>"sub_event_id"
end
I would use a plugin like Formtastic to accomplish this because it has support for various forms of ActiveRecord associations built into a solid alternative form handler. Just make sure you do an appropriate query with the most efficient join or include options for you model so that your view doesn't cause unnecessary database queries as it works through the associations.
As James says, Formtastic is a great way to go for this. And there are two great railscasts on how to use it.

Resources