ruby on rails,has_many,为多态关系定义类名

问题描述 投票:5回答:3

这是我从旧数据库中移动数据的代码:

class Old < ActiveRecord::Base
  establish_connection :old_version
  self.abstract_class = true

  class Recipe < self
    set_table_name :recipes
    has_many :uploaded_files, :as => :storage
  end

  class UploadedFile < self
    set_table_name :uploaded_files
    belongs_to :storage, :polymorphic => true
  end
end

当我运行以下代码时

Old::Recipe.all.each do |recipe|
  puts recipe.uploaded_files.to_sql
end

它执行此SQL

SELECT `uploaded_files`.* FROM `uploaded_files`  WHERE `uploaded_files`.`storage_id` = 38 AND `uploaded_files`.`storage_type` = 'Old::Recipe'

问题是我得到:

`storage_type` = 'Old::Recipe'

但是我需要:

`storage_type` = 'Recipe'

如何更改多态关系的类?

has_many的文档没有给我答案。

ruby-on-rails class polymorphism has-many
3个回答
4
投票

最近我有类似的问题,这是一个适用于我在rails 4.2中的解决方案:

class Recipe < self
  set_table_name :recipes
  has_many :old_files, -> (object) { unscope(where: :storage_type).where(storage_type: 'Recipe') }, class_name: 'UploadedFile'
end

您必须添加unscope(:where)以从查询中删除条件uploaded_files.storage_type = 'Old::Recipe'


2
投票

上面santuxus的答案适用于rails 4.2+

但是,对于较低版本,您可以尝试覆盖关联,如下所示:

class Recipe
  has_many :uploaded_files, conditions: { storage_type: 'Recipe' }, 
    foreign_key: :storage_id
end

0
投票

不幸的是,现在我发现只有一种方法可以做到这一点:

class Old < ActiveRecord::Base
  establish_connection :old_version
  self.abstract_class = true

  class Recipe < self
    set_table_name :recipes
    has_many :old_files,
             :class_name => 'UploadedFile',
             :finder_sql => Proc.new {
                %Q{
                  SELECT uploaded_files.*
                  FROM   uploaded_files
                  WHERE  uploaded_files.storage_id = #{id} AND
                         uploaded_files.storage_type = 'Recipe'
                }
              }
  end

  class UploadedFile < self
    set_table_name :uploaded_files
    belongs_to :storage, :polymorphic => true
  end
end


namespace :old do
  task :menu => :environment do
    Old::Recipe.all.each do |recipe|
      puts '~' * 50
      puts recipe.id
      recipe.old_files.to_a.each do |file|
        puts file.storage_id, file.storage_type
      end
    end
  end
end

非常非常伤心

© www.soinside.com 2019 - 2024. All rights reserved.