I have badges (sorta like *).
我有徽章(有点像*)。
Some of them can be attached to badgeable things (e.g. a badge for >X comments on a post is attached to the post). Almost all come in multiple levels (e.g. >20, >100, >200), and you can only have one level per badgeable x badge type (= badgeset_id
).
其中一些可以附加到可徽章的东西上(例如,帖子上附有> X评论的徽章附在帖子上)。几乎所有级别都有多个级别(例如> 20,> 100,> 200),并且每个可标记的x徽章类型(= badgeset_id)只能有一个级别。
To make it easier to enforce the one-level-per-badge constraint, I want badgings to specify their badge by a two-column foreign key - badgeset_id
and level
- rather than by primary key (badge_id
), though badges does have a standard primary key too.
为了更容易实施每个徽章的一级约束,我希望徽章通过两列外键 - badgeset_id和level - 而不是主键(badge_id)来指定徽章,尽管徽章确实有标准主键也是。
In code:
class Badge < ActiveRecord::Base
has_many :badgings, :dependent => :destroy
# integer: badgeset_id, level
validates_uniqueness_of :badgeset_id, :scope => :level
end
class Badging < ActiveRecord::Base
belongs_to :user
# integer: badgset_id, level instead of badge_id
#belongs_to :badge # <-- how to specify?
belongs_to :badgeable, :polymorphic => true
validates_uniqueness_of :badgeset_id, :scope => [:user_id, :badgeable_id]
validates_presence_of :badgeset_id, :level, :user_id
# instead of this:
def badge
Badge.first(:conditions => {:badgeset_id => self.badgeset_id, :level => self.level})
end
end
class User < ActiveRecord::Base
has_many :badgings, :dependent => :destroy do
def grant badgeset, level, badgeable = nil
b = Badging.first(:conditions => {:user_id => proxy_owner.id, :badgeset_id => badgeset,
:badgeable_id => badgeable.try(:id), :badgeable_type => badgeable.try(:class)}) ||
Badging.new(:user => proxy_owner, :badgeset_id => badgeset, :badgeable => badgeable)
b.level = level
b.save
end
end
has_many :badges, :through => :badgings
# ....
end
How I can specify a belongs_to
association that does that (and doesn't try to use a badge_id
), so that I can use the has_many :through
?
我如何指定执行该操作的belongs_to关联(并且不尝试使用badge_id),以便我可以使用has_many:through?
ETA: This partially works (i.e. @badging.badge works), but feels dirty:
ETA:这部分有效(即@ badging.badge有效),但感觉很脏:
belongs_to :badge, :foreign_key => :badgeset_id, :primary_key => :badgeset_id, :conditions => 'badges.level = #{level}'
Note that the conditions is in single quotes, not double, which makes it interpreted at runtime rather than loadtime.
请注意,条件是单引号,而不是double,这使得它在运行时而不是加载时进行解释。
However, when trying to use this with the :through association, I get the error undefined local variable or method 'level' for #<User:0x3ab35a8>
. And nothing obvious (e.g. 'badges.level = #{badgings.level}'
) seems to work...
但是,当尝试使用:through关联时,我得到错误未定义的局部变量或# <0x3ab35a8>0x3ab35a8>
<>>>>>>>>>>><>>>><>>>>>>>>>>
>>>>>><>>>><>>>>>
>>>>>><>>>><>>>>>