Sign in through GitHub

Please read for an updated status on RailsCasts:

Learn more or hide this

Mark Harper's Profile

GitHub User: markaharper

Comments by Mark Harper

Avatar

Hey Jorge,

You should be able to include cities if you had a "cities.csv" which matched the states structure.

To answer the other part of your question:

The "states.csv" and "countries.csv" data files are available in the github hosted "Source Code" under the "Show Notes" header:

https://github.com/railscasts/088-dynamic-select-menus-revised

By using the "db/seeds.rb" file you can migrate the data into any rails app.

bundle exec rake db:seeds

I hope this helps for future use.

Avatar

Hey Wayne,

The "states.csv" and "countries.csv" data files are available in the github hosted "Source Code" under the "Show Notes" header:

https://github.com/railscasts/088-dynamic-select-menus-revised

By using the "db/seeds.rb" file you can migrate the data into any rails app.

bundle exec rake db:seeds

I hope this helps for future use.

Avatar

P.S.

My code is a little different:

First, I got carrierwave working as per 253-carrierwave-file-uploads

then..

photos.js.coffee
jQuery ->
  $('#new_photo').fileupload
    dataType: "script"
    add: (e, data) ->
      types = /(\.|\/)(gif|jpe?g|png)$/i
      file = data.files[0]
      if types.test(file.type) || types.test(file.name)
        data.context = $(tmpl("template-upload", file).trim()) if $('#template-upload').length > 0
        $('#new_photo').append(data.context)
        data.submit()
      else
        alert("#{file.name} is not a gif, jpeg, or png image file")
    progress: (e, data) ->
      if data.context
        progress = parseInt(data.loaded / data.total * 100, 10)
        data.context.find('.progress-bar').css('width', progress + '%')
_form_uploader.html.erb
<%= simple_form_for [@gallery, @photo], :html => { :class => 'form-vertical' } do |f| %>
        <h3>Upload Photos Here</h3>
        <p>You can select multiple files.</p>
        <%= file_field_tag(:image, multiple: true, name: "photo[image]") %>                
<% end %>

<script id="template-upload" type="text/x-tmpl">
<div class="upload">
  {%=o.name%}
  <div class="progress progress-striped"><div class="progress-bar" style="width: 0%"></div></div>
</div>
</script>

<div id="uploads">
        <%= render 'uploads' %>
</div>
_uploads.html.erb
<ul id="photos" class="inline"><%= render @photos %></ul>
_photo.html.erb
<% if photo.id.present? %><li class="no-margin-padding pull-left"><a href="<%= photo.image_url() %>"><%= image_tag(photo.image_url(:icon)) if photo.image? %></a></li><% end %>
photos_controller.rb
  def create
    #on Gallery using to_param with 'auth_tokens' for securing user interface
    @gallery = Gallery.where("auth_token = ?", params[:id].to_s).first
    @photo = @gallery.photos.create(photo_params)
    respond_to do |format|
      format.html { redirect_to :back, notice: "Thank you for uploading" }
      format.js
      format.json { render json: [@photo.to_jq_upload].to_json, status: :created, location: @photo }
    end
  end
application.css
 *= require jquery.fileupload-ui
application.js
//= require jquery
//= require jquery_ujs
//= require jquery-ui
//= require jquery-fileupload/basic
//= require jquery-fileupload/vendor/tmpl
//= require jquery.fileupload-process
//= require photos
Gemfile
gem 'jquery-fileupload-rails'
gem "jquery-ui-rails"
Avatar

Hey All,

Bootstrap 3 modifications:

paintings.js.coffee
from:

data.context.find('.bar').css('width', progress + '%')

to:

data.context.find('.progress-bar').css('width', progress + '%')

And then

index.html.erb
from:

<div class="progress"><div class="bar" style="width: 0%"></div></div>

to:

<div class="progress progress-striped"><div class="progress-bar" style="width: 0%"></div></div>

I hope this helps. I f'd around with this for hours install all new css, js files before it dawned on me to update the bootstrap css.

To Your Success!!! Mark

Avatar

Hey... ... extremely late on this one - but just started a new app and needed reputation with pagination

try
@newsletters = Newsletter.approved.page(params[:page]).per_page(NEWSLETTERS_PER_PAGE).find_with_reputation(:votes, :all, order: "votes asc")

By placing the "find_with_reputation" after pagination (will_paginate) works.

Avatar

Try bbarton's suggestion - it worked for us.

from bbarton
modify...

where("to_tsvector('english', title) @@ :q", q: query)

... to..

where("to_tsvector('english', title) @@ plainto_tsquery(:q)", q: query)`

Also a couple of gotcha's was default scope and multiple includes.

We had to run the text_search as 'unscoped.where' and remove a couple of includes before any search results would displayed.

This app had one search query only on strings such as names, usernames, and email addresses (no full text searches). so we incorporated Ryan's Auto Completion:

http://railscasts.com/episodes/102-auto-complete-association-revised

It works great. Thank's Ryan!

Avatar

After upgrading to the latest jquery and adding Facebook 'Like' buttons, the sign-in popup window stopped functioning.

Firebug reported:

FB.getLoginStatus() called before calling FB.init().

To fix this, just move the "FB.init" call to the last position in facebook.js.coffee.erb.

app/assets/javascripts/facebook.js.coffee.erb
jQuery ->
  $('body').prepend('<div id="fb-root"></div>')

  $.ajax
    url: "#{window.location.protocol}//connect.facebook.net/en_US/all.js"
    dataType: 'script'
    cache: true


window.fbAsyncInit = ->

  $('#sign_in').click (e) ->
    e.preventDefault()
    FB.login (response) ->
      window.location = '/auth/facebook/callback' if response.authResponse

  $('#sign_out').click (e) ->
    FB.getLoginStatus (response) ->
      FB.logout() if response.authResponse
    true

  FB.init(appId: '<%= ENV["FACEBOOK_APP_ID"] %>', cookie: true)

Worked for me - not sure why.

Avatar

A BIG Thank You Egbert! - Worked for me!

Avatar

Maybe this can help those like Michael Elfassy, SMnetserv, pbaileyjr12 who have difficulty with double named countries.

On my app, everything worked fine until I accidentally 'bundle update' the gems.

After the bundle update, the double name countries (United States and United Kingdom) would not trigger and display the:

grouped_collection_select :state_id, Country.approved.includes(:states)

sidenote: bullet says to include states in the query.

I hope this helps:

app/assets/javascripts/people.js.coffee
original
escaped_country = country.replace(/([ #;&,.+*~\':"!^$[\][()=>|\/@])/g, '\\$1')

modified
escaped_country = country.replace(/([ #;&,.+*~\':"!^$[\][ ][()=>|\/@])/g, '\\$1')
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)