Quick question:
If I have a one-to-many relationship, such as this:
class SalesPerson < ActiveRecord::Base
has_many :deals
end
class Deal < ActiveRecord::Base
belongs_to :sales_person
end
how can I delete a Sales Person, without negatively impacting the deals associated with them? The use-case for this would be if someone left the organization. We still need a record of the deals in the database, but that sales person record is no longer needed.
Would it just be better to have an active/inactive flag on the sales person instead?
Thanks.
For this kind of situations I've use acts_as_paranoid, basically It adds a new timestamps column: deleted_at and overrides some of your AR finders.
Related
I need to solve two tasks in my rails app and i need some advice:
I have Person model and Car Model. One person can have only one car. it means that Car always has driver = person, but not each person has a car. So i need uni-directional One to One here. Is it possible to implement with rails? Actually i need has_one on Car and i don't need belongs_to on Person
I have Order and Load models. In my system there are many orders and when i am ready to deliver these orders I construct new Load object and put all orders which i want to deliver there. So every Load has_many orders but not each order belongs_to Load. It is uni-directional one-to-many... Also i don't need something like order.load, i need only load.orders
So how can I implement it with rails?
class Person < ActiveRecord::Base
has_one :car
end
class Load < ActiveRecord::Base
has_many :orders
end
Then you can call person_instance.car or load_instance.orders. You will have to have load_id on the orders and person_id on the cars
I have two models: Reader and Magazine. I obviously want to have a join table, readers_magazines, to represent which magazines each reader is subscribed to.
So I create my Reader model (with fields like name, address and age) and my Magazine model (with fields like Title and Active?). In each model I write has_and_belongs_to_many of the other.
Then I write a migration, CreateReadersMagazinesJoin, and write:
create_join_table :readers, :magazines do |t|
t.index 'reader_id'
t.index 'magazine_id'
end
And migrate the database. All good.
My question is... what now? Do I create a model for the join table? That seems wrong, and yet I do need some model validations (I don't want to represent the same User-Subscription combo twice). So do I write a model for it and manually specify the database table to use?
What is the correct procedure in this situation?
From the rails guides:
A has_and_belongs_to_many association creates a direct many-to-many
connection with another model, with no intervening model.
That means that using a has_and_belongs_to_many association might be easier for you to setup (because there is no middle model) but you don't have any kind of control over the join table, validations, etc. HABTM are normally considered harmful and you would want to use a has_many :through relationship instead, that is the same but having a model to represent the join table, so you have control over everything.
More information here.
Do I create a model for the join table? That seems wrong, and yet I do need some model validations.
If you don't want to add an additional fields to the join table, you don't really need to create the model for it.
And in most cases the validation that are required by yours, can be applied to one or both the tables.
I don't want to represent the same User-Subscription combo twice.
What do you mean twice, I havent seen the cases for that, however since the User-Subscription is something external the for the join table, you can explain more crear.
Where you have the choice between a habtm relationship or separate model, I would consider whether you need a rich amount of data in the join. In the present case, I think you do need extra data in the join. For example, a subscription would have a start date and an end date. It may also have a billing date and billing amount. You would not normally populate this information in a join table but rather in a stand alone model.
I would call the join table subscriptions and thus create a model Subscription. Then you can do it like this:
class Reader < ActiveRecord::Base
has_many :subscriptions
has_many :magazines, through: :subscriptions
end
class Subscription < ActiveRecord::Base
beongs_to :reader
belongs_to :magazine
end
class Magazine < ActiveRecord::Base
has_many :subscriptions
has_many :readers, through: :subscriptions
end
I am wondering how do I add additional properties to a many to many relationship.
I have two models that share a many to many relationship, Company and Profession.
Many professionals could belong to a Company
So my Company model looks like below
class Company < ActiveRecord::Base
has_and_belongs_to_many :professions
end
The same people in the same profession could belong to multiple companies as well
so
class Profession < ActiveRecord::Base
has_and_belongs_to_many :companies
end
Now I need to associate an hourly rate which could be different for each of the companies for the same profession. I am not very sure where to introduce the hourly rate property? Even if I were to add that to the joining table, how do I access that rate using active record?
This is a typical scenario where you select has_many through over habtm. As a rule, if you only need to associate two models, no other info needed to be stored in the association, use habtm. For most cases, you have to use has_many through. You case falls under this scenario.
You want to save the hourly rate in the table that associates a Profession and a Company. If you have existing data that you want to migrate, you may want to look at this post How to migrate has_and_belongs_to_many to has_many through?. If you can drop the joins table you use for the habtm association, just drop it and create a new table.
I'm trying to implement something similar to that below. Basic setup is a Schedule model
class Schedule < ActiveRecord::Base
has_many :events
end
The Event model will then belong_to a Schedule.
Events are comprised of a name, datetime, running length and a Room
A Room is chosen from a select list when the event is created, all Rooms are created beforehand through seeding or admin interface. Room will store information like seating count.
I've been trying to find a method implementing this that feels right. Solutions seem to range between habtm or has_many :through but I can't see the need for a join table for this situation.
Theoretically, an Event has_one :room but the reverse relationship isn't belongs_to :event as a Room may be used for many events, this also requires the foreign key to be on the rooms table.
I've considered handling this manually in the model using a room_id foreign key in the event, I could then query for the relevant Room. I think this would work since I currently cannot see a requirement for finding all events using a Room.
class Event < ActiveRecord::Base
belongs_to :schedule
def room
Room.find(room_id)
end
end
Everything I've done so far in Rails has felt 'right', but all the solutions I've come up with here doesn't and I feel like I'm missing something; or maybe I'm just expecting that extra bit of magic.
Is there a "Rails" way to do this?
Wouldn't Event just have a belongs_to relationship to Room in this case?
class Event < ActiveRecord::Base
belongs_to :schedule
belongs_to :room
end
If you think about it from a schema perspective, your "events" table almost certainly has "schedule_id" and "room_id" columns.
The other side of the relationship is that a Room has_many Events.
I'm a beginning to ROR, but here's what I'm trying to achieve. I have two items I want to associate: matters and people. Each matter can have many people. That is, I want to create people and matters separately and later be able to link them.
For example, I may create:
Bill Clinton
Barack Obama
I may create the matters:
Global warming
War on terror
I want to be able to associate the users Bill Clinton AND Barack Obama to BOTH matters. Can someone point me to a tutorial that can show me how to do this?
I think has_and_belongs_to_many is used less and less by the RoR community now. While still supported, I think it is now more common to have an intermediate model (in your case something like PoliticianMatter) to join your Politician and Matter models.
Then your politician_matter table will have a PK, a politician_id and a matter_id.
Then you have
class PoliticanMatter < ActiveRecord::Base
belongs_to :politician
belongs_to :matter
end
The advantage of this approach is that if there ever need to be future properties of the politician -> matter relationship (e.g importance, date of last occurrence) you have a model which affords this - has_and_belongs_to_many would not support the addition of these extra properties.
You can also access the many to many relationship directly from the Politician and Matter models like this
class Politician < ActiveRecord::Base
has_many :politician_matters
has_many :matters, :through => :politician_matters
end
class Matter < ActiveRecord::Base
has_many :politician_matters
has_many :politicians, :through => :politician_matters
end
You need a many2many relationship between these two entities.
A matter can be studied by many people
A person can studie several matters
Rails uses the has_and_belongs_to_many helper to do that. You'll find more about that in the documentation and many many blog posts!
has_and_belongs_to_many helper
class Politician < ActiveRecord::Base
has_and_belongs_to_many :tasks
end
class Task < ActiveRecord::Base
has_and_belongs_to_many :politicians
end
What you need are 3 tables:
politicians, tasks and politicians_tasks (having the two columns politician_id and task_id, no primary key)
Hope this helps
Seb