Rails中是否可以为belongs_to关联创建别名?

54

我有一个带有 belongs_to 关联的模型:

class Car < ActiveRecord::Base
  belongs_to :vendor
end

所以我可以调用car.vendor。但是我也想调用car.company!所以,我有以下代码:

class Car < ActiveRecord::Base
  belongs_to :vendor
  def company
    vendor
  end
end

但这并不能解决赋值的情况 car.company = 'ford',所以我需要创建另一个方法。是否有一种简单的别名机制可以用于关联?我是否可以只使用alias_method :company, :vendoralias_method :company=, :vendor=

4个回答

82

不,它不会查找 company_id。例如,将您的代码更改如下

在Rails 3中

class Car < ActiveRecord::Base
   belongs_to :vendor
   belongs_to :company, :class_name => :Vendor,:foreign_key => "vendor_id"
end

在Rails4中

我们可以使用别名属性。

alias_attribute :company, :vendor

1
不幸的是,reflect_on_association与后者不兼容。 - Will I AM
1
Rails 4的语法简洁明了,但只有在您的语法完美无缺时才能正常工作。通过执行belongs_to :company, class_name: :Vendor, foreign_key: "vendor_id",您实际上更好地掌握了变量的语法,并可以将其用作中间步骤以实现“简洁”。 - Jerome

33
在Rails 4中,您只需在模型中添加alias_attribute :company, :vendor即可。

4
好的建议!只需指出:使用alias_attribute仍然可以访问companyvendor属性,而使用仅限于关系belongs_to :company, :class_name => :Vendor,:foreign_key => "vendor_id"会隐藏属性vendor - Hilder Vitor Lima Pereira

13

简短版:

  1. Generate model with migration

    $ rails generate model Car vendor:references name:string ...

  2. Add following line in Car model i.e car.rb file

    class Car < ActiveRecord::Base
      belongs_to :company, :class_name => 'Vendor', :foreign_key => 'vendor_id'
    end
    
  3. Now you have @car.company instance method.

详细解释请往下看[如果您已经理解上述内容,则此步骤可跳过!!]

详细版:

模型Car将与模型Vendor相关联(这是显而易见的)。因此,表cars中应该有一个vendor_id

  1. In order to make sure that the field vendor_id is present in the cars table run the following on the command line. This will generate the right migration. The vendor:references is important. You can have any number of attributes after that.

    $ rails generate model Car vendor:references name:string

  2. Or else in the existing migration for create_table :cars just add the line t.references :vendor

    class CreateCars < ActiveRecord::Migration
      def change
        create_table :cars do |t|
          t.string :name
          ...
          t.references :vendor
          t.timestamps
        end
      end
    end
    
  3. The final thing that you need to do is edit the model Car. So add this code to your car.rb file

    class Car < ActiveRecord::Base
      belongs_to :company, :class_name => 'Vendor', :foreign_key => 'vendor_id'
    end
    
完成第三个步骤后,您将获得Rails Associations提供的以下用于模型Car的实例方法。
  1. @car.company

    • When you do @car.company it will return a #<Vendor ...> object. To find that #<Vendor ...> object it will go look for the vendor_id column in the cars table because you have mentioned :foreign_key => 'vendor_id'

    • You can set the company for a car instance by writing

      @car.company = @vendor || Vendor.find(params[:id]) #whichever Vendor object you want
      @car.save
      

      This will save the id of that Vendor object in the vendor_id field of the cars table.

感谢您。

4
class Car < ActiveRecord::Base
  belongs_to :vendor
  belongs_to :company, :class_name => :Vendor
end

1
这不会在数据库中查找company_id字段吗? - at.
不,至少在Rails 4.2中是这样的。经过一些测试,似乎列名是由使用的类决定的,而不是关联属性的名称。因此,belongs_to :company, class_name: :Vendor 将在您的表中搜索一个名为 vendor_id 的列 - 而不指定 class_name 选项将自动解析为使用类名 Company 并搜索 company_id 列。尽管如此,提供 foreign_key: 选项仍然可能被认为是更好的实践,以帮助消除未来的问题。 - wes.hysell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接