Rails:在一个视图中从三个相关模型收集数据
我是一个尝试构建我的第一个 Rails 应用程序的菜鸟。这是一种“投注游戏”,用户尝试预测足球结果并获得正确结果或正确“趋势”(获胜、平局、失败)的积分。
创建和更新投注工作正常,还以管理员用户身份创建游戏和插入结果。但是我在以某种索引页面显示每个游戏的所有用户的所有投注时遇到问题,该页面大致应如下所示:
| User1 | User2 | User3 ...
Game Result | Bet | Bet | Bet
Team1 : Team2 1:0 | 1:1 | 3:2 | 1:0
Team3 : Team4 1:2 | 1:2 | -:- | 3:0
Team5 : Team6 -:- | 1:2 | -:- | 3:0
...
我的模型结构如下所示:
class User < ActiveRecord::Base
has_many :bets
class Game < ActiveRecord::Base
has_many :bets
class Bet < ActiveRecord::Base
belongs_to :user, :class_name => 'User', :foreign_key => 'user_id'
belongs_to :game, :class_name => 'Game', :foreign_key => 'game_id'
由上面的 scetch 中的 -:- 指示,而不是每个用户都会在每场比赛中下注,但并不是每场比赛都会有结果。
我尝试了一千种方法来为索引视图收集数据,但遇到了多个错误(nil 对象、无方法等)的问题。当前(不起作用)的方法是将所有内容都放在控制器中:
def index
@users = User.all
@games = Game.all
@bets = Bet.all
end
并在视图中尝试通过视图中的用户和赌注迭代到游戏和每个游戏中,同时检查用户和游戏的赌注是否存在,这会导致那里出现不可读的混乱代码:
<% @games.each do |game| %>
<tr>
<td><%= game.home_team %> - <%= game.away_team %></td>
<td>
<% if game.away_score.nil? %>
-:-
<% else %>
<%= game.home_score %> : <%= game.away_score %>
<% end -%>
</td>
<% @users.each do |user| %>
<% bet = Bet.where( :user_id => user.id, :game_id => game.id) %>
<% if bet.exists? %>
<td><%= bet.home_bet %> : <%= bet.away_bet %></td>
<% else %>
<td>-:-</td>
<% end -%>
<% end -%>
</tr>
<% end -%>
我希望您能提出一种更清晰的方法来完成此任务。不幸的是,我读的几十篇文章都不能解决我的问题。
因此,第一个问题是:从不同表中检索所需数据的最佳方法是什么?对应的第二个问题:最好是在控制器中构建数据并将其传递给视图还是将它们全部放在视图中?
我正在使用 Rails 3.1.1 和 sqlite3。 我希望有人能帮助这个愚蠢的新手......
I'm a noob trying to build up my first rails app. It's a "betting game" where users try to predict football results and get points for correct result or correct "tendency" (win, draw, loose).
Creating and updating bets is working fine, also creating games and inserting results as an admin user. But I'm having problems in displaying all bets from all users for each game in a kind of an index page, which should roughly look like this:
| User1 | User2 | User3 ...
Game Result | Bet | Bet | Bet
Team1 : Team2 1:0 | 1:1 | 3:2 | 1:0
Team3 : Team4 1:2 | 1:2 | -:- | 3:0
Team5 : Team6 -:- | 1:2 | -:- | 3:0
...
My Model structure looks like this:
class User < ActiveRecord::Base
has_many :bets
class Game < ActiveRecord::Base
has_many :bets
class Bet < ActiveRecord::Base
belongs_to :user, :class_name => 'User', :foreign_key => 'user_id'
belongs_to :game, :class_name => 'Game', :foreign_key => 'game_id'
Indicated by the -:- in the above scetch, not every user will have placed a bet on every game, and not every game will have a result.
I tried a thousand ways of getting the data together for the index view and got issues with multiple errors (nil object, no method etc.). The current (not working) approach is getting everything in the controller:
def index
@users = User.all
@games = Game.all
@bets = Bet.all
end
and in the view trying to iterate to the games and within each games through the users and bets in the view, while checking if a bet of a user and a game exists, which leads to unreadable messy code there:
<% @games.each do |game| %>
<tr>
<td><%= game.home_team %> - <%= game.away_team %></td>
<td>
<% if game.away_score.nil? %>
-:-
<% else %>
<%= game.home_score %> : <%= game.away_score %>
<% end -%>
</td>
<% @users.each do |user| %>
<% bet = Bet.where( :user_id => user.id, :game_id => game.id) %>
<% if bet.exists? %>
<td><%= bet.home_bet %> : <%= bet.away_bet %></td>
<% else %>
<td>-:-</td>
<% end -%>
<% end -%>
</tr>
<% end -%>
I hope you can suggest a cleaner way to accomplish this. Unfortunately, none of the dozens of posts I read could solve my problem.
So, the first question is: what is the best way to retrieve the needed data from the different tables? Corresponding second Question: Is it best to build the data in the controller and pass it to the view or put it all together in the view?
I'm using rails 3.1.1 with squlite3.
I hope, someone can help this stupid newbee...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这里有很多问题......让我们开始
没有必要遍历每个游戏的所有用户。您可以迭代
game.bets
并通过bet.user
为每个“赌注”获取一个用户,根据您建立的关系,
回答您的第一个问题:由于您正在尝试制作“报告”类型的视图,旨在显示“所有”游戏,因此您使用
@games = Game.all
的方法是正确的。不过,您不需要另外 2 个.all
集合,因为您可以从关系中推断出数据第二个问题:在 Rails 中,它被认为是拥有“胖模型、瘦控制器”的好方法这意味着您的数据处理/逻辑代码应该位于模型中,并且控制器应该只有相应视图使用的代码。
if
So many issues here... let's start
there's no need to iterate through ALL users for EACH game. You can iterate through
game.bets
and for each 'bet' get a user bybet.user
, according to the relationship you have builtTo answer your 1st question: since you are trying to make a 'report' kind of a view with an intent to show 'all' games, your approach to have
@games = Game.all
is right. You don't need 2 other.all
collections though since you can infer the data from the relationships2nd question: In Rails it is considered a good approach to have 'fat models, skinny controllers' which means that your data crunching/logic code should be in a model and controller should have only code used by the correspondent views.
About your view: In your case your view is not terribly bad since you have a sparsely populated tables and you should use
if
s for cases where score is not available etc我可能会做这样的事情:
控制器:
视图:
I would probably do something like this:
controller:
view: