Sign in through GitHub

Mark Harper's Profile

GitHub User: markaharper

Comments by Mark Harper

Avatar

How to have only active announcement ids in the cookies.signed[:hidden_announcement_ids]

This is kind of 'amateur hour' code (my specialty), but:

After using site-wide-announcements for several months, the development log was passing several dozen expired ids on each page load:

SELECT "announcements".* 
  FROM "announcements" 
  WHERE (starts_at <= '2013-03-18 06:55:20.343948' and ends_at >= '2013-03-18 06:55:20.343948') 
  AND (id not in (10,9,23,45,32,12,6,7,8,76,4,8,90,5,43,2,67,54,3,2,6,5,67,89,2,8,9,7,54,6,7,32,24,56,77,7,53,2,1)) 
  ORDER BY id desc

I got tired of looking at all those ids, so as a test I tried to figure out how to have only active announcement ids in the cookies.signed[:hidden_announcement_ids].

Deleting the cookie was simple, but would re-display previously hidden announcements.

Here's my solution.

An 'active' name scope (id in (?)), as opposed to the 'current' scope (id not in (?))

models/announcement.rb
  def self.active(hidden_ids = nil)
    result = where("starts_at <= :now and ends_at >= :now", now: Time.zone.now)
    result = result.where("id in (?)", hidden_ids) if hidden_ids.present?
    result
  end

An after_filter :flush_announcement_cookie, placed on the users' login landing dashboard_controller.

dashboard_controller
  after_filter :flush_announcement_cookie

  def flush_announcement_cookie
    if cookies.signed[:hidden_announcement_ids].present?      
      ids = Announcement.active(cookies.signed[:hidden_announcement_ids]).pluck(:id)
      cookies.permanent.signed[:hidden_announcement_ids] = ids
    end
  end

Hope this helps somebody.

Avatar

Here's a simple multi-rating system for Photos based of Ryan's videocast. It is simple: just pass the value as the params[:type]: vote_photo_path(photo, type: "1"). Aalso using twitter/bootstrap/font_awesome for the vote icons

vote:
Notice the current_user cannot vote on their own photos;

And I included a 'status' attribute for 'Approved' or 'Denied' the display/hide the photo from public viewing.

Automatic Quality Control: Notice the automatic status change to 'Denied' is ONLY after 10 votes and with an average value less than 3.

vote_range:
This is in the application_controller.rb because I use the reputation system on several models: Ads, Photos, Profiles.

vote_reset:
This allows for resetting the values.

voteable?:
Allows control of who can vote

models/photo.rb
  has_reputation :review_photos, source: :user
  scope :public, where("status = ?", "Approved")
models/user.rb
  has_reputation :review_photos, :source => { :reputation => :review_photos, :of => :photos }
controllers/photos_controller.rb
def vote
      
    @photo = Photo.find(params[:id])
    
    if current_user
        
      if @photo.user_id != current_user.id
      
        value = params[:type]
  
        if vote_range?(value)
          @photo.add_or_update_evaluation(:review_photos, value, current_user)
        end
        
           # if low score on photo - automatically update status to "Denied" to hide from "Public" - @photos = Photo.public

        if @photo.reputation_for(:review_photos).to_i < 3 && @photo.evaluations.count >= 10
          @photo.status = "Denied"
          @photo.save
        end

      end
      
    end

    respond_to do |format|
      format.html { redirect_to :back, notice: "Thank you for voting" }
      format.js
    end
  end
 
  def vote_reset
        
    @photo = Photo.find(params[:id])
    
    if @photo.present?
      
      evaluations = @photo.evaluations
      evaluations.each do |eval|
        eval.destroy
      end
      
      reputations = @photo.reputations
      reputations.each do |rep|
        rep.destroy
      end
      
      @photo.status = "Approved"
      @photo.save

    end
controllers/application_controller.rb
  def vote_range?(value)
    value.to_i.between?(-3,10)
  end
  helper_method :vote_range?

  def votable?
    if user_signed_in?
      if add - your - criteria - for example...
        if current_user.status == "Approved"
          true
        end
      end
    end
  end
  helper_method :votable?
views/photos/_vote.html.erb
<div id="review_photo_<%= photo.id %>" class="center star_bar">

    <%= photo.reputation_for(:review_photos).to_i %> points | avg score <%= photo.evaluations.average('value').to_i %> |
ranked <%= photo.rank_for(:review_photos).to_i %>


        <% if votable? %>
                <%= link_to vote_photo_path(photo, type: "-3"), method: "post", remote: true, :title => "-3 point" do %>
                  <i class="icon-thumbs-down"></i>
                <% end %>
                <%= link_to vote_photo_path(photo, type: "1"), method: "post", remote: true, :title => "1 point" do %>
                  <i class="icon-star"></i>
                <% end %>
                <%= link_to vote_photo_path(photo, type: "2"), method: "post", remote: true, :title => "2 points" do %>
                  <i class="icon-star"></i>
                <% end %>
                <%= link_to vote_photo_path(photo, type: "3"), method: "post", remote: true, :title => "3 points" do %>
                  <i class="icon-star"></i>
                <% end %>
                <%= link_to vote_photo_path(photo, type: "4"), method: "post", remote: true, :title => "4 points" do %>
                  <i class="icon-star"></i>
                <% end %>
                <%= link_to vote_photo_path(photo, type: "5"), method: "post", remote: true, :title => "5 points" do %>
                  <i class="icon-star"></i>
                <% end %>
                <%= link_to vote_photo_path(photo, type: "10"), method: "post", remote: true, :title => "10 points" do %>
                  <i class="icon-heart"></i>
                <% end %>
        <% end %>

</div>
views/photos/vote.js
  $('#review_photo_<%= @photo.id %>').hide().after('<%= j render("voted") %>');
views/photos/_voted.html.erb
<div id="review_photo_<%= @photo.id %>" class="center star_bar">
        <% if !user_signed_in? %>
                Please Login to Vote
        <% elsif @photo.user_id == current_user.id %>
                Don't Vote on Your Photos
        <% else %>
                Thank You!
        <% end %>
</div>

I hope this helps

Avatar

Hey if you get: undefined method `reputation_value_for'

change `reputation_value_for' to 'reputation_for'

reputation_value_for was deprecated and replaced by reputation_for, see commit (10/03/2012)

reputation_for(reputation_name, *args)

https://github.com/twitter/activerecord-reputation-system/commit/552c04b0dead76cd79fb3915845b17b6a8de0cca

Also normalized_reputation_value_for was deprecated and replaced by normalized_reputation_for

normalized_reputation_for(reputation_name, *args)