轨道5.1.2 Ruby 2.5.3
我知道可以通过多种方式暗示这种关系,但是,这个问题更多地是关于为什么以下内容不起作用而不是解决现实世界中的问题。
class _RoulettePageWidgetState extends State<RoulettePageWidget>
with SingleTickerProviderStateMixin {
Animation<double> _animation;
Tween<double> _tween;
AnimationController _animationController;
math.Random _random = math.Random();
int position = 0;
double getRandomAngle() {
return math.pi * 2 / 25 * _random.nextInt(25);
}
@override
void initState() {
super.initState();
_animationController =
AnimationController(duration: Duration(seconds: 2), vsync: this);
_tween = Tween(begin: 0.0, end: getRandomAngle());
_animation = _tween.animate(_animationController)
..addListener(() {
setState(() {});
});
}
void setNewPosition() {
_tween.begin = _tween.end;
_animationController.reset();
_tween.end = getRandomAngle();
_animationController.forward();
}
@override
Widget build(BuildContext context) {
return Container(
child: Column(
children: <Widget>[
Center(
child: Transform.rotate(
angle: _animation.value,
child: Icon(
Icons.arrow_upward,
size: 250.0,
),
)),
Expanded(
child: Container(),
),
RaisedButton(
child: Text('SPIN'),
onPressed: setNewPosition,
)
],
)
);
}
}
设置
has_many
在上面的class Subscriber < ApplicationRecord
has_many :subscriptions, inverse_of: :subscriber
has_many :promotions, through: :subscriptions, inverse_of: :subscriptions
accepts_nested_attributes_for :subscriptions
accepts_nested_attributes_for :promotions
end
class Subscription < ApplicationRecord
belongs_to :subscriber, inverse_of: :subscriptions
belongs_to :promotion, inverse_of: :subscriptions
end
class Promotion < ApplicationRecord
has_many :subscriptions, inverse_of: :promotion
has_many :subscribers, through: :subscriptions, inverse_of: :subscriptions
accepts_nested_attributes_for :subscriptions
accepts_nested_attributes_for :subscribers
end
模型中,该模型被设置为使用Subscriber
关系,如下所示:
has_many
在此之后,我希望s = Subscriber.new
s.subscriptions.build
# OR
s.promotions.build
在Subscriber
关系中的行为方式相同
has_one
设置
has_one
但是,尝试使用等效的class Subscriber < ApplicationRecord
has_one :subscription, inverse_of: :subscriber
has_one :promotion, through: :subscription, inverse_of: :subscriptions
accepts_nested_attributes_for :subscription
accepts_nested_attributes_for :promotion
end
class Subscription < ApplicationRecord
belongs_to :subscriber, inverse_of: :subscription
belongs_to :promotion, inverse_of: :subscriptions
end
class Promotion < ApplicationRecord
has_many :subscriptions, inverse_of: :promotion
has_many :subscribers, through: :subscriptions, inverse_of: :subscription
accepts_nested_attributes_for :subscriptions
accepts_nested_attributes_for :subscribers
end
构建方法来构建嵌套的promotion
关联会导致has_one
错误
NoMethodError (undefined method 'build_promotion' for #<Subscriber:0x00007f9042cbd7c8>)
但是,这确实可行:
s = Subscriber.new
s.build_promotion
我认为应该以建立s = Subscriber.new
s.build_subscription
的相同方式来建立嵌套的has_one
关系,这是合乎逻辑的。
这是错误还是故意的?
答案 0 :(得分:1)
检查代码,当您调用has_one时,仅当反射是“可构造的”时,它才会创建build_
,create_
和create_..!
方法
define_constructors(mixin, name) if reflection.constructable?
现在,检查constructable?
方法,它返回calculate_constructable
https://github.com/rails/rails/blob/ed1eda271c7ac82ecb7bd94b6fa1b0093e648a3e/activerecord/lib/active_record/reflection.rb#L452
对于HasOne类,如果使用:through
选项https://github.com/rails/rails/blob/ed1eda271c7ac82ecb7bd94b6fa1b0093e648a3e/activerecord/lib/active_record/reflection.rb#L723
def calculate_constructable(macro, options)
!options[:through]
end
所以,我想说这不是错误,它是设计使然。不过我不知道原因,也许听起来很合逻辑,但是我想有些事情要考虑的并不那么简单。