2012-10-14 74 views
1

我正在为俱乐部制作该软件,人们只需登录并添加分数,球员,球队等。现在我当然有许多俱乐部,并且对于每种模型都有club_id列来识别该俱乐部。有一些更容易获得最新的俱乐部比写类似这样:Ruby on Rails:在每个模型中应用程序范围过滤

News.where("club_id = ?", @club_id)

我发现它太难摘要proplem这么多,我能找到任何答案。

回答

1

一种方式是进行一些基本类为您的机型:

class ClubStuff < ActiveRecord::Base 
    self.abstract_class = true # <--- don't forget 
    default_scope { where(club_id: Thread.current[:club_id]) } 
end 

,使你的模型出来的:

class News < ClubStuff 

然后:

# in ApplicationController 
before_filter { Thread.current[:club_id] = params[:club_id] } 

希望你有这个想法。

+0

是的,那正是我希望找到的解决方案出来了!我想过范围(我仍然不得不每次都写它来查询),但没有意识到有这个default_scope功能。 Rails太棒了!谢谢大家的答案。 –

0

为什么在RoR的每个模型中都有默认的id属性时创建一个额外的id(club_id)?您可以使用此代码

News.find(id)。

如果你仍然坚持,那么替代代码:

News.find_by_club_id(@club_id)

+0

我选择了不好的例子,我想..我的坏。我经常需要列举属于该俱乐部的球队,以便代码看起来像这样:Team.where(“club_id =?”,@club_id).all'这并不是每次都很复杂的方式我需要选择属于该俱乐部的所有东西 –

0

那么你可以在之前的控制器的过滤器写一些。使用您的Team示例:

class TeamController < AC 
    before_filter :get_club, :only => [ :index ] # you can limit the filter to methods 

    def index 
    # because of the before filter you can access club here 
    @teams = @club.teams 
    end 

    # ... 

    private 
    def get_club 
    @club = Club.find(params[:club_id]) 
    end 
end 

此行为也可以移入模块中。有关过滤器的更多信息,请参阅here

+0

这是一个很好的解决方案,当我将滤波器添加到AC中时它更加少量,因此它可用于所有控制器。我仍然想知道是否可以通过某些模型级别的功能来管理它,例如从某个基类派生所有模型,然后在基类中过滤属于其他俱乐部的所有事物,任何想法?我认为这对于安全性来说也是相当不错的,因为其他俱乐部的数据无法从其他俱乐部管理功能访问 –

+0

要将这种逻辑移入模型中,它实际上会打破MVC模式,因为控制器在那里你的观点和你的模型。至于安全性,通过上述技巧,您可以使用CanCan(https://github.com/ryanb/cancan)等功能限制其他俱乐部管理员查看不属于他们的数据。这绝对是更清洁的解决方案。如果你将它们转移到你的模型中,你仍然必须通过控制器与它们进行通信,这会导致类似'find_by_club_id'这样的事情,恐怕... – Vapire