Rails:在使用模型名称空间时在一个地方指定foreign_key / parent_class

时间:2016-04-28 18:53:12

标签: ruby-on-rails ruby

我决定将所有用户逻辑移到单独的文件夹app/models/user/*中。 我们说我有文件main.rb,它定义了常量User::Main

当我运行rspec测试时,我发现几乎每个关联测试都失败了。

问题是Rails不知道

belongs_to :user

表示因为不再有User常数。

Rails试图找到错误的外键:

User::Main.last.build_api_token
ActiveRecord::UnknownAttributeError: unknown attribute 'main_id' for ApiToken.

所以有一个解决方案:我需要像这样更改每个belongs_to

belongs_to :user, class_name: 'User::Main'

(至少我可以使用顾虑)

我需要指定每个foreign_key

has_many :api_tokens, foreign_key: "user_id"

但是,在许多不同的文件/行中进行大量额外编辑是必要的。

对于第一个问题,我可以使用关注模块,但第二个呢?

如何为所有孩子设置一次外键,Rails将通过该外键进行关联。

module User
 class Main < ActiveRecord::Base
   self.accessible_by_key "user_id" #pseudocode to illustrate what I think of
 end
end

P.S。我找到了add_foreign_key docs,但不确定它是否是我要找的。

1 个答案:

答案 0 :(得分:0)

如果我做对了,你想要完成的是模块化你的用户模型,你可以使用以下方法:

  1. user.rb(模型)保留在app/models文件夹内的常用位置。

  2. app/models/concerns内创建一个模块;例如user_common.rb

  3. user_common.rb内,您可以拥有以下内容:

    #app/models/concerns/user_common.rb
    
    module UserCommon
    
      extend ActiveSupport::Concern
    
      included do
        validates :email, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i }
      end
    
      def custom_method
    
      end
      ...
    end
    
  4. 在您的用户模型中,只需调用模块:

    #app/models/user.rb
    
    class User < ActiveRecord::Base
    
      include UserCommon
    
      ...
    end 
    
  5. 我希望有所帮助。