开发者

Determining the status of associated models in a class

I have a Rails 2.3 app which tracks an organisation's members, and whether they have a paid membership. Some members may not have a paid membership, some may have a 1-year paid membership, and some may have a lifetime membership. We wish to record a member's membership history.

Currently I have the following (relevant) models and schema:

class Member < ActiveRecord::Base
   has_many :memberships
end

class Membership < ActiveRecord::Base
   belongs_to :member
end

create_table "members", :force => true do |t|
  t.string  "name"
  t.datetime "created_at"
  t.datetime "updated_at"
end

create_table "memberships", :force => true do |t|
  t.string   "name"
  t.integer  "member_id"
  t.datetime "end_date"
  t.boolean  "lifetime"
end

At the moment we determine whether a client is a current member in the view, which of course is not a best practice, so we want to move the logic to the model. The code in the view is:

<% if @memberships.count == 0 %>
  This member has never had a paid membership
<% else %>
  <% if @memberships.last.lifetime? %>
    This member is a lifetime member
  <% else %>
    <% if @memberships.last.end_date < Time.now %>
      This member's membership has expired
    <% else %>
      <% if @memberships.last.end_date > Time.now %>
        This member is a current member
      <% end %>
    <% end %>
  <% end %>
&开发者_如何学编程lt;% end %>

What I'd like is for a (for example) current_member method and a lifetime_member method in the Member class, which will return true or false. I've had a play at doing this, but I'm not sure which is the best way to do it.

Any suggestions?


General case:

class Member  
  def current_member?
    if memberships.count > 0
      memberships.each{ |m| return true if m.lifetime || m.end_date > Time.now }
    end
    return false
  end

  def lifetime_member?
    if memberships.count > 0
      memberships.each{ |m| return true if m.lifetime }
    end
    return false
  end
end

If you're sure that you want to check only the last membership:

class Member
  def lifetime_member?
    return memberships.count > 0 && memberships.last.lifetime
  end

  def current_member?
    return memberships.count > 0 && (memberships.last.lifetime || memberships.last.end_date > Time.now }
  end  
end


Here's is how I might go about moving the logic to the model.

class Member < ActiveRecord::Base
   has_many :memberships

   def current_membership
     memberships.last
   end

   def has_membership?
     memberships.any?
   end

   def active?
     !expired?
   end

   def expired?
     !lifetime? && (current_membership.active? if current_membership)
   end

   def lifetime?
     current_membership.lifetime? if current_membership
   end
end


class Membership < ActiveRecord::Base
   belongs_to :member

   def active?
     !expired
   end

   def expired?
     end_date < Time.now
   end

end

Here's is what you might write in erb:

<% unless @member.has_membership? %>
  This member has never had a paid membership
<% end %>

<% if @member.lifetime? %>
  This member is a lifetime member
<% end %>

<% if @member.expired?%>
  This member's membership has expired
<% end %>

<% if @member.active? %>
  This member is a current member
<% end %>

And the same in HAML, which I recommend:

- unless @member.has_membership?
  This member has never had a paid membership

- if @member.lifetime?
  This member is a lifetime member

- if @member.expired?
  This member's membership has expired

- if @member.active?
  This member is a current member
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜