2条导轨模型之间的关联路径



,所以我有一些轨道型号。这是一个类似的示例列表:

  • 一所房子属于一个社区
  • 一个社区属于一个城市
  • 一个城市属于一个国家
  • 一个国家属于一个国家
  • 一个用户属于房屋

我想获得一个非常神奇的功能,我可以使用如下:

(resource, scope, scope_ids) => {...}

成功的电话看起来像:

("house", "country", [30]) => { neighborhood: { city: { state: { country: [30] } } } }
("house", "state", [1,2,3]) => { neighborhood: { city: { state: [1,2,3] } } }

和一个失败的呼叫将返回:

("house", "people", [1,2,3]) => { id: -1 }

我想自动进行此操作,以便任何经过硬编码的东西都是不可接受的。

编辑:

我想实现上述结果,因为我正在使用cancancan开发授权层,允许做以下事情:

can :read, House, { neighborhood: { city: { state: { name: "Illinois" }}}}

考虑了上述语法,我想自动产生权限,例如(例如," ownoughtorhood"是被授权的用户的内居性,而" ershots_houses"与被授权的用户的房屋不同(:

# permission read_own_neighborhood_houses should generate:
can :read, House, { neighborhood: { users: {id: user.id } }
# permission read_own_state_cities should generate:
can :read, City, { state: { cities: { houses: { users: {id: user.id } } } } } } }
# permission read_others_neighborhoods_states should generate: 
can :read, State, { cities: { neighborhoods: { houses: { users: { id: User.where.not(id: user.id) } } } } }

这当然需要大量的元编程。这可能是使用reflections_on_all_associations方法的开始...

给定permission read_own_state_cities

def permission(perms)
  @perms = perms.split('_')  #['read', 'own', 'state', 'cities']
  @model = @perms[-1].singularize.capitalize.constantize   #City
  @action = @perms[0].to_sym   #:read
  @ownership = @perms[1].to_sym   #:own
  @top_level = @perms[2]   #:state
  hash_items = []
  current_level = @top_level
  until current_level = :user do
    hash_items << current_level
    current_level = current_level.reflect_on_all_associations(:has_many).first.name.to_sym
  end   #[:state, :cities, :neighborhoods]
  @hash = hash_items.reverse.inject({users: {}}) { |a, n| { n => a } } #{state: {cities: {neigborhoods: {users: {}}}}}
end

这是我很容易获得的,而没有您的实际情况进行测试。您需要根据@ownership的值来解决如何确定users: {}哈希的内容。这应该为您提供最终即时建立can....所需的一切。

最新更新