How best to associate an Address to multiple models in rails?

前端 未结 2 2141
余生分开走
余生分开走 2021-02-20 02:31

This question on SO appears to be related to my question, but I\'m not sure my question is answered by that.

An address can belong to more than one model (UserProfile an

相关标签:
2条回答
  • 2021-02-20 03:28

    You missed one option: have a class that contains the common behavior and add the fields to all tables. Use a composed_of aggregate to manage the data.

    class Address
      attr_accessor :line1, :line2, :city, :state, :zip
    
      def initialize(line1, line2, city, state, zip)
        @line1 = line1
      end
    end
    
    class UserProfile < ActiveRecord::Base
      composed_of :address, :mapping => %w(line1 line2 city state zip)
    end
    
    class Event < ActiveRecord::Base
      composed_of :address, :mapping => %w(line1 line2 city state zip)
    end
    

    See #composed_of in the Ruby on Rails API docs.

    0 讨论(0)
  • 2021-02-20 03:34

    One way would be standard Rails polymorphism:

    class Address
      belongs_to :addressable, :polymorphic => true
    end
    
    class UserProfile
      has_one address, :as => :addressable
    end
    
    class Event
      has_one address, :as => :addressable
    end
    

    It could be the nagging feeling you have about this is that you can't create a db-level constraint with Rails-style polymorphic relationships. The alternative (suggested by Dan Chak in Enterprise Rails) is like your #1 option, where you do indeed create a separate id field for each type of relationship. This does leave unused fields, but it also allows for constraints. I can see the argument for both, but the Rails community has been using AR polymorphism for some time with apparently good success. I use it without hesitation. But if that bugs you, you can use Chak's approach. It's a lot more work. : )

    EDIT: @Slick86, migration would look something like:

    class CreateAddresses < ActiveRecord::Migration
      def change
        create_table :addresses do |t|
          t.integer :addressable_id
          t.string :addressable_type
        end
      end
    end
    
    0 讨论(0)
提交回复
热议问题