我已经做了一些关于如何扩展ActiveRecord:Base类的阅读,所以我的模型会有一些特殊的方法.扩展它的简单方法是什么(逐步教程)?
从Rails 2.3开始,将一个目录添加到加载路径的正确方法是什么,以便它挂钩到Rails的自动重载机制?
我正在考虑的具体示例是我有一个使用STI有几个子类的类,我认为将它们放在子目录中而不是混乱顶级是一个好主意.所以我会有类似的东西:
#app/models/widget.rb
class Widget < ActiveRecord::Base
add_to_load_path File.join(File.dirname(__FILE__), "widgets")
end
#app/models/widgets/bar_widget.rb
class BarWidget < Widget
end
#app/models/widgets/foo_widget.rb
class FooWidget < Widget
end
Run Code Online (Sandbox Code Playgroud)
这add_to_load_path是我正在寻找的方法.
我有一个ActiveSupport :: Concern模块,看起来大致如下:
module MyModel
module Acceptance
extend ActiveSupport::Concern
included do
enum status: [:declined, :accepted]
end
def declined!
self.status = :declined
# some extra logic
self.save!
end
def accepted!
self.status = :accepted
# some extra logic
self.save!
end
end
end
Run Code Online (Sandbox Code Playgroud)
这只会被包含在ActiveRecord类中,因此使用enum.基本上,我正在用我自己的一些额外的自定义逻辑来覆盖declined!和accepted!创建的方法ActiveRecord::Enum.enum.
问题是,这不起作用,因为当我调用@model.declined!它时只需调用原始实现declined!并忽略我的自定义方法.
看起来我的自定义方法在运行包含块之前被包含在调用类中- 这意味着我的自定义方法被定义的方法覆盖enum,而不是相反.
在这种特殊情况下有一些简单的解决方法(例如,我可以将调用enum移回到包含类并确保它在线上include MyModel::Acceptance,但我想知道是否有一种方法可以解决这个问题,同时将它保存在同一个模块中.
有没有办法可以在included定义实例方法中调用类方法,然后在同一个Concern模块中覆盖该实例方法?
ruby overriding ruby-on-rails activesupport activesupport-concern
我正在尝试将STI和多态关联与以下结构相结合的一些问题:
class User < ActiveRecord::Base
end
class Runner < User
has_many :subscriptions, as: :subscriber, :dependent => :destroy
has_many :areas, through: :subscriptions
end
class Trainer < Runner
end
class Subscription < ActiveRecord::Base
belongs_to :subscriber, polymorphic: true
belongs_to :area
end
class Area
end
Run Code Online (Sandbox Code Playgroud)
当我在控制台中尝试时:
Runner.find(2101).areas
SELECT "areas".* FROM "areas" INNER JOIN "subscriptions" ON "areas"."id" =
"subscriptions"."area_id" WHERE "subscriptions"."subscriber_id" = $1 AND
"subscriptions"."subscriber_type" = $2 [["subscriber_id", 2101], ["subscriber_type",
"User"]]
=> #<ActiveRecord::Associations::CollectionProxy []>
Run Code Online (Sandbox Code Playgroud)
但是这个跑步者有一个记录:
#<Subscription id: 3, area_id: 2, subscriber_id: 2101, subscriber_type: "Runner", primary_area: …Run Code Online (Sandbox Code Playgroud) 我有rails关系的问题.我有基础模型蚂蚁他继承的版本
class User < ActiveRecord::Base
end
class Admin < User
end
Run Code Online (Sandbox Code Playgroud)
接下来我有多态关联的成员模型
class Membership < ActiveRecord::Base
belongs_to :group
belongs_to :membershipable, polymorphic: true
end
Run Code Online (Sandbox Code Playgroud)
当我尝试创建成员模型的新实例时,通过键入例如
Membership.new group: Group.first, membershipable: Admin.first
Run Code Online (Sandbox Code Playgroud)
membershipable_type设置为"User"而不是"Admin".所以我创建了before_validation回调
def proper_sti_type
self.membershipable_type = memebrshipable.class.name
end
Run Code Online (Sandbox Code Playgroud)
它的工作原理,但我想这是更好的方法.也许有人知道更好的解决方案?
谢谢
汤姆
我有两个使用该people表的模型:Person和Person::Employee(继承自Person).该people表有一type列.
还有另一个模型,Group它具有多态关联,称为:owner.该groups表包含owner_id列和owner_type列.
应用程序/模型/ person.rb:
class Person < ActiveRecord::Base
has_one :group, as: :owner
end
Run Code Online (Sandbox Code Playgroud)
应用程序/模型/人/ employee.rb:
class Person::Employee < Person
end
Run Code Online (Sandbox Code Playgroud)
应用程序/模型/ group.rb:
class Group < ActiveRecord::Base
belongs_to :owner, polymorphic: true
belongs_to :supervisor
end
Run Code Online (Sandbox Code Playgroud)
问题是,当我使用以下代码创建Person :: Employee时,该owner_type列设置为不正确的值:
group = Group.create
=> #<Group id: 1, owner_id: nil, owner_type: nil ... >
group.update owner: Person::Employee.create
=> true
group
=> …Run Code Online (Sandbox Code Playgroud) ruby model ruby-on-rails polymorphic-associations ruby-on-rails-4