首先,一些背景知识。
我的应用程序模型如下:
User has_many :subscriptions; has_many :courses, :through => :subscriptions
Subscription belongs_to :course, :user
Course has_many :subscriptions; has_many :users, :through => :subscriptions
订阅是一个连接表,用于存储诸如state(:active,:inactive,:failed,:passed,:unpaid)之类的信息,以及作为连接课程所带来的所有信息的连接器(例如作为等级模型(尚未添加),付款模式(正在进行中)等。)
我想添加付款模式以存储订阅的付款历史记录。每笔付款可以用于一个或多个订阅。到目前为止,我已经尝试了Payment has_many :subscriptions
,但我遇到了控制器逻辑问题,我想也许有更好的方法可以将模型与“订阅课程的用户。“
从技术上讲,在付款展示操作中,我需要来自每个模型的信息(course.name,付费用户的user_id,payment.amount,所有这些都与订阅相关联)和付款。创建动作,我需要设置订阅状态(我能做到)。
如果这是将各种模型关联起来的逻辑/有效方式,那么如何使用最少的数据库调用在Payment show操作中访问所需信息(来自每个模型课程,用户,付款和订阅的一些信息)?我正在使用Rails 3.2/Ruby 1.9
,并希望坚持使用ActiveRecord / ARel而不是直接的sql语句。我也乐于接受“你做错了”的答案。如果更改关联将使从控制器访问表更有效,我也会对此持开放态度。
答案 0 :(得分:1)
做(config/routes.rb
)
resources :users do
resources :courses do
resources :subscriptions
end
end
这将允许您执行@user.courses.subscriptions
例如,如果您想从courses
返回users
,则可以将路线修改为
resources :users, :shallow => true do
#...
end
修改强>
对于付款,我会像你说的那样has_many :subscriptions
当您出示付款时。你会做类似
的事情payment_history = Payment.find(params[:id])
@subscriptions = payment_history.subscriptions
现在您拥有该付款历史记录链接的订阅列表,例如
您将在视图中循环并显示每个订阅
<% @subscriptions.each do |subscription|%>
<%= subscription.payment.id %>
<%= subscription.users.size %>
<%= subscription.courses.size %>
<%= subscription.paying_user.name %> <!-- or whereever it exists-->
<% end%>
您需要确保有路由并在更改路径后重新启动服务器
resources :payments, :shallow => true do
resources :subscriptions
end
答案 1 :(得分:1)
@ D3mon-1stVFW的答案让我走上了正确的道路来解决这个问题。
对于付款节目操作,查询将类似于:
@payment = Payment.find_by_id(params[:id])
@subscriptions = @payment.subscriptions.includes(:course, :user)
这样就可以访问与订阅相关的课程和用户数据,如下所示:
<% @subscriptions.each do |subscription|%>
<%= subscription.payment.amount %>
<%= subscription.user.email %>
<%= subscription.course.name %>
<%= subscription.state %>
<% end%>
对于尚未payment.id
的付款新/创建操作,查询略有不同:
@unpaid_subs = Subscription.where(:user_id => current_user.id).unpaid.includes(:course)
@payment = Payment.new
current_user
是要支付的用户(创建新的付款),而.unpaid
是Subscription
模型的范围,如下所示:
scope :unpaid, -> { where('subscriptions.payment_id' => nil)}
在视图中,您可以使用与show视图相同的方式访问数据:
<% @unpaid_subs.each do |sub| %>
<%= sub.course.name %> | <%= sub.course.credits %><br />
<% end %>
我的主要困惑在于我不知道你可以从孩子那里获得父母协会。订阅belongs_to课程,但您仍然可以subscription.course.something
。