我有兴趣设置一些常用的关联(除其他外),但我需要根据使用关注点的类进行一些小的调整。我的基本关注点如下:
module Organizable
extend ActiveSupport::Concern
included do
has_many :person_organizations
has_many :organizations,
through: :person_organizations,
class_name: <STI CLASS NAME HERE>
end
end
```
如您所见,我希望能够更改组织关联中的班级名称。
我在想我可以包含一些类方法来提供这种支持,但是我无法知道如何继续获取这个值。以下是我看到自己使用它的方式:
class Dentist < Person
include Organizable
organizable organization_class: DentistClinic
end
这是我当前的代码版本:
module Organizable
extend ActiveSupport::Concern
module ClassMethods
attr_reader :organization_class
private
def organizable(organization_class:)
@organization_class = organization_class
end
end
included do
has_many :person_organizations
has_many :organizations,
through: :person_organizations,
class_name: self.class.organization_class.name
end
end
我认为至少有两个问题:
1)在建立关联时似乎没有定义.organization_class
方法,因为当我加载时,我得到了Class:Class`的NoMethodError: undefined method
organization_class'牙医模型。
2)我想在我甚至将该类传递给关注点(organizable organization_class: DentistClinic
行)之前,将评估关注点内的关联,因此它无论如何都不会包含值。
我真的不确定如何解决这个问题。有没有办法将此参数传递给关注点并使用此值设置关联?
这不是How to create a Rails 4 Concern that takes an argument
的副本我正在做几乎就是那篇文章中概述的内容。我的用例不同之处在于我正在尝试使用该参数来配置在Concern中定义的关联。
答案 0 :(得分:1)
我遇到了类似的问题,我需要根据模型本身的参数在“关注事项”中定义自定义关联。
我发现的解决方案(在Rails 5.2中进行了测试,但其他版本应该相似)是在类方法中定义关系,类似于Mirza建议的答案。
这是代码示例, 问题:
require 'active_support/concern'
module Organizable
extend ActiveSupport::Concern
included do
has_many :person_organizations
end
class_methods do
def organization_class_name(class_name)
has_many :organizations,
through: :person_organizations,
class_name: class_name
end
end
end
模型:
class Dentist < Person
include Organizable
organization_class_name DentistClinic
end
我也更愿意按照您在答案中所建议的那样做,看起来更干净,但这需要在included do
之前对类方法进行评估和使用。
基本上,我需要的是在关联定义中使用关注参数的方法,这是最直接的方法,如果有人需要,我会把它留在这里。
答案 1 :(得分:0)
一种解决方案是将动态模块包含在类中。
import React from 'react';
import { listConnectionNames } from './where-ever-the-list-connection-name-file-is.js';
class App extends React.Component {
state = {
data: null
};
componentDidMount() {
listConnectionNames().then((data) => {
this.setState({
data,
});
});
};
render() {
console.log(this.state.data);
return <div>Hello World</div>;
};
}
还没有测试过,但是应该可以工作。
module Organizable
extend ActiveSupport::Concern
def organizable(klass)
Module.new do
extend ActiveSupport::Concern
included do
has_many :person_organizations
has_many :organizations,
through: :person_organizations,
class_name: klass
end
end
end
end