Added recipe search; bumped gems and ruby version

This commit is contained in:
Dan Elbert 2017-03-29 16:52:59 -05:00
parent 977e0e8d6a
commit afc2793375
9 changed files with 237 additions and 175 deletions

View File

@ -1 +1 @@
2.3.1 2.4.1

View File

@ -1,4 +1,4 @@
FROM phusion/passenger-ruby23:latest FROM phusion/passenger-ruby24:latest
# Use baseimage-docker's init process. # Use baseimage-docker's init process.
CMD ["/sbin/my_init"] CMD ["/sbin/my_init"]

14
Gemfile
View File

@ -1,8 +1,8 @@
source 'https://rubygems.org' source 'https://rubygems.org'
gem 'rails', '5.0.0' gem 'rails', '5.0.2'
gem 'sqlite3' gem 'sqlite3'
gem 'pg', '~> 0.18.4' gem 'pg', '~> 0.20.0'
gem 'sass-rails', '~> 5.0' gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0' gem 'uglifier', '>= 1.3.0'
@ -12,11 +12,11 @@ gem 'puma'
gem 'therubyracer', platforms: :ruby gem 'therubyracer', platforms: :ruby
# Use jquery as the JavaScript library # Use jquery as the JavaScript library
gem 'jquery-rails', '~> 4.1.1' gem 'jquery-rails', '~> 4.3.1'
gem 'bootstrap-sass', '~> 3.3.6' gem 'bootstrap-sass', '~> 3.3.7'
gem 'kaminari', '~> 0.17.0' gem 'kaminari', '~> 1.0.1'
gem 'turbolinks', '~> 5.0.0' gem 'turbolinks', '~> 5.0.1'
gem 'jbuilder', '~> 2.5' gem 'jbuilder', '~> 2.6'
gem 'cocoon', '~> 1.2.9' gem 'cocoon', '~> 1.2.9'
gem 'unitwise', '~> 2.0.0' gem 'unitwise', '~> 2.0.0'

View File

@ -1,59 +1,59 @@
GEM GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
actioncable (5.0.0) actioncable (5.0.2)
actionpack (= 5.0.0) actionpack (= 5.0.2)
nio4r (~> 1.2) nio4r (>= 1.2, < 3.0)
websocket-driver (~> 0.6.1) websocket-driver (~> 0.6.1)
actionmailer (5.0.0) actionmailer (5.0.2)
actionpack (= 5.0.0) actionpack (= 5.0.2)
actionview (= 5.0.0) actionview (= 5.0.2)
activejob (= 5.0.0) activejob (= 5.0.2)
mail (~> 2.5, >= 2.5.4) mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0) rails-dom-testing (~> 2.0)
actionpack (5.0.0) actionpack (5.0.2)
actionview (= 5.0.0) actionview (= 5.0.2)
activesupport (= 5.0.0) activesupport (= 5.0.2)
rack (~> 2.0) rack (~> 2.0)
rack-test (~> 0.6.3) rack-test (~> 0.6.3)
rails-dom-testing (~> 2.0) rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.2) rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (5.0.0) actionview (5.0.2)
activesupport (= 5.0.0) activesupport (= 5.0.2)
builder (~> 3.1) builder (~> 3.1)
erubis (~> 2.7.0) erubis (~> 2.7.0)
rails-dom-testing (~> 2.0) rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.2) rails-html-sanitizer (~> 1.0, >= 1.0.3)
activejob (5.0.0) activejob (5.0.2)
activesupport (= 5.0.0) activesupport (= 5.0.2)
globalid (>= 0.3.6) globalid (>= 0.3.6)
activemodel (5.0.0) activemodel (5.0.2)
activesupport (= 5.0.0) activesupport (= 5.0.2)
activerecord (5.0.0) activerecord (5.0.2)
activemodel (= 5.0.0) activemodel (= 5.0.2)
activesupport (= 5.0.0) activesupport (= 5.0.2)
arel (~> 7.0) arel (~> 7.0)
activesupport (5.0.0) activesupport (5.0.2)
concurrent-ruby (~> 1.0, >= 1.0.2) concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (~> 0.7) i18n (~> 0.7)
minitest (~> 5.1) minitest (~> 5.1)
tzinfo (~> 1.1) tzinfo (~> 1.1)
arel (7.1.2) arel (7.1.4)
autoprefixer-rails (6.5.0) autoprefixer-rails (6.7.7.1)
execjs execjs
bcrypt (3.1.11) bcrypt (3.1.11)
blankslate (3.1.3) blankslate (3.1.3)
bootstrap-sass (3.3.7) bootstrap-sass (3.3.7)
autoprefixer-rails (>= 5.2.1) autoprefixer-rails (>= 5.2.1)
sass (>= 3.3.4) sass (>= 3.3.4)
builder (3.2.2) builder (3.2.3)
byebug (9.0.5) byebug (9.0.6)
cocoon (1.2.9) cocoon (1.2.9)
coderay (1.1.1) coderay (1.1.1)
concurrent-ruby (1.0.2) concurrent-ruby (1.0.5)
database_cleaner (1.5.3) database_cleaner (1.5.3)
debug_inspector (0.0.2) debug_inspector (0.0.2)
diff-lcs (1.2.5) diff-lcs (1.3)
erubis (2.7.0) erubis (2.7.0)
execjs (2.7.0) execjs (2.7.0)
factory_girl (4.7.0) factory_girl (4.7.0)
@ -61,11 +61,11 @@ GEM
factory_girl_rails (4.7.0) factory_girl_rails (4.7.0)
factory_girl (~> 4.7.0) factory_girl (~> 4.7.0)
railties (>= 3.0.0) railties (>= 3.0.0)
ffi (1.9.14) ffi (1.9.18)
formatador (0.2.5) formatador (0.2.5)
globalid (0.3.7) globalid (0.3.7)
activesupport (>= 4.1.0) activesupport (>= 4.1.0)
guard (2.14.0) guard (2.14.1)
formatador (>= 0.2.4) formatador (>= 0.2.4)
listen (>= 2.7, < 4.0) listen (>= 2.7, < 4.0)
lumberjack (~> 1.0) lumberjack (~> 1.0)
@ -79,18 +79,27 @@ GEM
guard (~> 2.1) guard (~> 2.1)
guard-compat (~> 1.1) guard-compat (~> 1.1)
rspec (>= 2.99.0, < 4.0) rspec (>= 2.99.0, < 4.0)
i18n (0.7.0) i18n (0.8.1)
jbuilder (2.6.0) jbuilder (2.6.3)
activesupport (>= 3.0.0, < 5.1) activesupport (>= 3.0.0, < 5.2)
multi_json (~> 1.2) multi_json (~> 1.2)
jquery-rails (4.1.1) jquery-rails (4.3.1)
rails-dom-testing (>= 1, < 3) rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0) railties (>= 4.2.0)
thor (>= 0.14, < 2.0) thor (>= 0.14, < 2.0)
kaminari (0.17.0) kaminari (1.0.1)
actionpack (>= 3.0.0) activesupport (>= 4.1.0)
activesupport (>= 3.0.0) kaminari-actionview (= 1.0.1)
libv8 (3.16.14.15) kaminari-activerecord (= 1.0.1)
kaminari-core (= 1.0.1)
kaminari-actionview (1.0.1)
actionview
kaminari-core (= 1.0.1)
kaminari-activerecord (1.0.1)
activerecord
kaminari-core (= 1.0.1)
kaminari-core (1.0.1)
libv8 (3.16.14.19)
liner (0.2.4) liner (0.2.4)
listen (3.1.5) listen (3.1.5)
rb-fsevent (~> 0.9, >= 0.9.4) rb-fsevent (~> 0.9, >= 0.9.4)
@ -98,7 +107,7 @@ GEM
ruby_dep (~> 1.2) ruby_dep (~> 1.2)
loofah (2.0.3) loofah (2.0.3)
nokogiri (>= 1.5.9) nokogiri (>= 1.5.9)
lumberjack (1.0.10) lumberjack (1.0.11)
mail (2.6.4) mail (2.6.4)
mime-types (>= 1.16, < 4) mime-types (>= 1.16, < 4)
memoizable (0.4.2) memoizable (0.4.2)
@ -108,65 +117,63 @@ GEM
mime-types-data (~> 3.2015) mime-types-data (~> 3.2015)
mime-types-data (3.2016.0521) mime-types-data (3.2016.0521)
mini_portile2 (2.1.0) mini_portile2 (2.1.0)
minitest (5.9.1) minitest (5.10.1)
multi_json (1.12.1) multi_json (1.12.1)
nenv (0.3.0) nenv (0.3.0)
nio4r (1.2.1) nio4r (2.0.0)
nokogiri (1.6.8) nokogiri (1.7.1)
mini_portile2 (~> 2.1.0) mini_portile2 (~> 2.1.0)
pkg-config (~> 1.1.7)
notiffany (0.1.1) notiffany (0.1.1)
nenv (~> 0.1) nenv (~> 0.1)
shellany (~> 0.0) shellany (~> 0.0)
parslet (1.7.1) parslet (1.7.1)
blankslate (>= 2.0, <= 4.0) blankslate (>= 2.0, <= 4.0)
pg (0.18.4) pg (0.20.0)
pkg-config (1.1.7)
pry (0.10.4) pry (0.10.4)
coderay (~> 1.1.0) coderay (~> 1.1.0)
method_source (~> 0.8.1) method_source (~> 0.8.1)
slop (~> 3.4) slop (~> 3.4)
puma (3.6.0) puma (3.8.2)
rack (2.0.1) rack (2.0.1)
rack-test (0.6.3) rack-test (0.6.3)
rack (>= 1.0) rack (>= 1.0)
rails (5.0.0) rails (5.0.2)
actioncable (= 5.0.0) actioncable (= 5.0.2)
actionmailer (= 5.0.0) actionmailer (= 5.0.2)
actionpack (= 5.0.0) actionpack (= 5.0.2)
actionview (= 5.0.0) actionview (= 5.0.2)
activejob (= 5.0.0) activejob (= 5.0.2)
activemodel (= 5.0.0) activemodel (= 5.0.2)
activerecord (= 5.0.0) activerecord (= 5.0.2)
activesupport (= 5.0.0) activesupport (= 5.0.2)
bundler (>= 1.3.0, < 2.0) bundler (>= 1.3.0, < 2.0)
railties (= 5.0.0) railties (= 5.0.2)
sprockets-rails (>= 2.0.0) sprockets-rails (>= 2.0.0)
rails-controller-testing (1.0.1) rails-controller-testing (1.0.1)
actionpack (~> 5.x) actionpack (~> 5.x)
actionview (~> 5.x) actionview (~> 5.x)
activesupport (~> 5.x) activesupport (~> 5.x)
rails-dom-testing (2.0.1) rails-dom-testing (2.0.2)
activesupport (>= 4.2.0, < 6.0) activesupport (>= 4.2.0, < 6.0)
nokogiri (~> 1.6.0) nokogiri (~> 1.6)
rails-html-sanitizer (1.0.3) rails-html-sanitizer (1.0.3)
loofah (~> 2.0) loofah (~> 2.0)
railties (5.0.0) railties (5.0.2)
actionpack (= 5.0.0) actionpack (= 5.0.2)
activesupport (= 5.0.0) activesupport (= 5.0.2)
method_source method_source
rake (>= 0.8.7) rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0) thor (>= 0.18.1, < 2.0)
rake (11.3.0) rake (12.0.0)
rb-fsevent (0.9.7) rb-fsevent (0.9.8)
rb-inotify (0.9.7) rb-inotify (0.9.8)
ffi (>= 0.5.0) ffi (>= 0.5.0)
ref (2.0.0) ref (2.0.0)
rspec (3.5.0) rspec (3.5.0)
rspec-core (~> 3.5.0) rspec-core (~> 3.5.0)
rspec-expectations (~> 3.5.0) rspec-expectations (~> 3.5.0)
rspec-mocks (~> 3.5.0) rspec-mocks (~> 3.5.0)
rspec-core (3.5.3) rspec-core (3.5.4)
rspec-support (~> 3.5.0) rspec-support (~> 3.5.0)
rspec-expectations (3.5.0) rspec-expectations (3.5.0)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
@ -183,8 +190,8 @@ GEM
rspec-mocks (~> 3.5.0) rspec-mocks (~> 3.5.0)
rspec-support (~> 3.5.0) rspec-support (~> 3.5.0)
rspec-support (3.5.0) rspec-support (3.5.0)
ruby_dep (1.4.0) ruby_dep (1.5.0)
sass (3.4.22) sass (3.4.23)
sass-rails (5.0.6) sass-rails (5.0.6)
railties (>= 4.0.0, < 6) railties (>= 4.0.0, < 6)
sass (~> 3.1) sass (~> 3.1)
@ -194,26 +201,26 @@ GEM
shellany (0.0.1) shellany (0.0.1)
signed_multiset (0.2.1) signed_multiset (0.2.1)
slop (3.6.0) slop (3.6.0)
sprockets (3.7.0) sprockets (3.7.1)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
rack (> 1, < 3) rack (> 1, < 3)
sprockets-rails (3.2.0) sprockets-rails (3.2.0)
actionpack (>= 4.0) actionpack (>= 4.0)
activesupport (>= 4.0) activesupport (>= 4.0)
sprockets (>= 3.0.0) sprockets (>= 3.0.0)
sqlite3 (1.3.11) sqlite3 (1.3.13)
therubyracer (0.12.2) therubyracer (0.12.3)
libv8 (~> 3.16.14.0) libv8 (~> 3.16.14.15)
ref ref
thor (0.19.1) thor (0.19.4)
thread_safe (0.3.5) thread_safe (0.3.6)
tilt (2.0.5) tilt (2.0.7)
turbolinks (5.0.1) turbolinks (5.0.1)
turbolinks-source (~> 5) turbolinks-source (~> 5)
turbolinks-source (5.0.0) turbolinks-source (5.0.0)
tzinfo (1.2.2) tzinfo (1.2.3)
thread_safe (~> 0.1) thread_safe (~> 0.1)
uglifier (3.0.2) uglifier (3.1.11)
execjs (>= 0.3.0, < 3) execjs (>= 0.3.0, < 3)
unitwise (2.0.0) unitwise (2.0.0)
liner (~> 0.2) liner (~> 0.2)
@ -225,7 +232,7 @@ GEM
activemodel (>= 5.0) activemodel (>= 5.0)
debug_inspector debug_inspector
railties (>= 5.0) railties (>= 5.0)
websocket-driver (0.6.4) websocket-driver (0.6.5)
websocket-extensions (>= 0.1.0) websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.2) websocket-extensions (0.1.2)
@ -234,28 +241,28 @@ PLATFORMS
DEPENDENCIES DEPENDENCIES
bcrypt (~> 3.1.11) bcrypt (~> 3.1.11)
bootstrap-sass (~> 3.3.6) bootstrap-sass (~> 3.3.7)
byebug byebug
cocoon (~> 1.2.9) cocoon (~> 1.2.9)
database_cleaner (~> 1.5.3) database_cleaner (~> 1.5.3)
factory_girl_rails (~> 4.7.0) factory_girl_rails (~> 4.7.0)
guard (~> 2.14.0) guard (~> 2.14.0)
guard-rspec guard-rspec
jbuilder (~> 2.5) jbuilder (~> 2.6)
jquery-rails (~> 4.1.1) jquery-rails (~> 4.3.1)
kaminari (~> 0.17.0) kaminari (~> 1.0.1)
pg (~> 0.18.4) pg (~> 0.20.0)
puma puma
rails (= 5.0.0) rails (= 5.0.2)
rails-controller-testing rails-controller-testing
rspec-rails (~> 3.5.0) rspec-rails (~> 3.5.0)
sass-rails (~> 5.0) sass-rails (~> 5.0)
sqlite3 sqlite3
therubyracer therubyracer
turbolinks (~> 5.0.0) turbolinks (~> 5.0.1)
uglifier (>= 1.3.0) uglifier (>= 1.3.0)
unitwise (~> 2.0.0) unitwise (~> 2.0.0)
web-console (~> 3.3.1) web-console (~> 3.3.1)
BUNDLED WITH BUNDLED WITH
1.13.1 1.14.6

View File

@ -3,6 +3,31 @@
$(document).on("turbolinks:load", function() { $(document).on("turbolinks:load", function() {
$(".recipe-view ul.ingredients").checkable(); $(".recipe-view ul.ingredients").checkable();
$(".recipe-view ol.steps").checkable(); $(".recipe-view ol.steps").checkable();
var $searchBtn = $("#recipe_index_search_button");
if ($searchBtn.length) {
var $form = $("#search_form");
var $nameInput = $("#name_search");
var $tagsInput = $("#tags_search");
$form.submit(function() {
$("#criteria_name").val($nameInput.val());
$("#criteria_tags").val($tagsInput.val());
});
$searchBtn.click(function(evt) {
$form.submit();
});
$nameInput.add($tagsInput).on('keydown', function(evt) {
if (evt.which == 13) {
console.log('keydown enter pressed');
$form.submit();
}
});
}
}); });
})(jQuery); })(jQuery);

View File

@ -1,4 +1,5 @@
class Recipe < ApplicationRecord class Recipe < ApplicationRecord
include TokenizedLike
has_many :recipe_ingredients, -> { order :sort_order }, inverse_of: :recipe, dependent: :destroy has_many :recipe_ingredients, -> { order :sort_order }, inverse_of: :recipe, dependent: :destroy
has_many :recipe_steps, -> { order :sort_order }, inverse_of: :recipe, dependent: :destroy has_many :recipe_steps, -> { order :sort_order }, inverse_of: :recipe, dependent: :destroy
@ -9,7 +10,6 @@ class Recipe < ApplicationRecord
scope :undeleted, -> { where('deleted <> ? OR deleted IS NULL', true) } scope :undeleted, -> { where('deleted <> ? OR deleted IS NULL', true) }
scope :not_log, -> { where('is_log <> ? OR is_log IS NULL', true) } scope :not_log, -> { where('is_log <> ? OR is_log IS NULL', true) }
scope :active, -> { undeleted.not_log } scope :active, -> { undeleted.not_log }
scope :for_criteria, ->(criteria) { active.order(criteria.sort_column => criteria.sort_direction).page(criteria.page).per(criteria.per) }
accepts_nested_attributes_for :recipe_ingredients, allow_destroy: true accepts_nested_attributes_for :recipe_ingredients, allow_destroy: true
accepts_nested_attributes_for :recipe_steps, allow_destroy: true accepts_nested_attributes_for :recipe_steps, allow_destroy: true
@ -104,6 +104,21 @@ class Recipe < ApplicationRecord
copy copy
end end
def self.for_criteria(criteria)
query = active.order(criteria.sort_column => criteria.sort_direction).page(criteria.page).per(criteria.per)
if criteria.name.present?
query = query.matches_token(:name, criteria.name)
end
if criteria.tags.present?
tags = Tag.by_name(criteria.tags.split)
query = query.where(id: tags.joins(:recipes).pluck('recipes.id'))
end
query
end
private private
def calculate_nutrition_data def calculate_nutrition_data

View File

@ -1,6 +1,8 @@
class Tag < ApplicationRecord class Tag < ApplicationRecord
include TokenizedLike include TokenizedLike
has_and_belongs_to_many :recipes
scope :by_name, ->(names) { where(lowercase_name: Array.wrap(names).map { |n| n.downcase }) } scope :by_name, ->(names) { where(lowercase_name: Array.wrap(names).map { |n| n.downcase }) }
validates :name, presence: true, length: {maximum: 250}, uniqueness: { case_sensitive: false } validates :name, presence: true, length: {maximum: 250}, uniqueness: { case_sensitive: false }

View File

@ -2,13 +2,13 @@ module ViewModels
class RecipeCriteria class RecipeCriteria
SORT_COLUMNS = :created_at, :name, :rating, :total_time SORT_COLUMNS = :created_at, :name, :rating, :total_time
PARAMS = [:sort_column, :sort_direction, :page, :per, :name, :tags]
attr_writer :sort_column, :sort_direction attr_accessor *PARAMS
attr_writer :page, :per
def initialize(params = {}) def initialize(params = nil)
params ||= {} params ||= {}
([:sort_column, :sort_direction, :page, :per]).each do |attr| PARAMS.each do |attr|
setter = "#{attr}=" setter = "#{attr}="
if params[attr] if params[attr]
self.send(setter, params[attr]) self.send(setter, params[attr])
@ -17,31 +17,29 @@ module ViewModels
end end
def sort_column def sort_column
@sort_column ||= SORT_COLUMNS.first default(@sort_column.to_s.to_sym, SORT_COLUMNS.first, ->(v) {SORT_COLUMNS.include?(v)} )
@sort_column = @sort_column.to_sym
unless SORT_COLUMNS.include? @sort_column
@sort_column = SORT_COLUMNS.first
end
@sort_column
end end
def sort_direction def sort_direction
@sort_direction ||= :asc default(@sort_direction.to_s.to_sym, :desc, ->(v) {[:asc, :desc].include?(v)} )
@sort_direction = @sort_direction.to_sym
unless [:asc, :desc].include? @sort_direction
@sort_direction = :asc
end
@sort_direction
end end
def page def page
@page.to_i || 1 default(@page, 1, ->(v) { v.to_i > 0 })
end end
def per def per
@per.to_i || 50 default(@per, 50, ->(v) { v.to_i > 0 })
end
protected
def default(val, default_val, valid_proc)
if val.blank? || !valid_proc.call(val)
default_val
else
val
end
end end
end end

View File

@ -5,70 +5,85 @@
<h1>Recipes</h1> <h1>Recipes</h1>
</div> </div>
<% if current_user? %>
<%= link_to 'New Recipe', new_recipe_path, class: 'btn btn-default' %><br/>
<% end %>
<%= paginate @recipes %>
<%= form_for(@criteria, as: :criteria, url: recipes_path, method: :get, html: {id: 'search_form'}) do |f| %>
<%= f.hidden_field :sort_column %>
<%= f.hidden_field :sort_direction %>
<%= f.hidden_field :page %>
<%= f.hidden_field :per %>
<%= f.hidden_field :name %>
<%= f.hidden_field :tags %>
<% end %>
<div class="table-responsive">
<table class="recipe-table table table-striped table-hover">
<thead>
<tr>
<th><%= index_sort_header('Name', :name, @criteria) %></th>
<th>Tags</th>
<th><%= index_sort_header('Rating', :rating, @criteria) %></th>
<th>Yields</th>
<th><%= index_sort_header('Time', :total_time, @criteria) %></th>
<th><%= index_sort_header('Created', :created_at, @criteria) %></th>
<th></th>
</tr>
<tr>
<th><%= text_field_tag('name_search', @criteria.name) %></th>
<th><%= text_field_tag('tags_search', @criteria.tags) %></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th><button id="recipe_index_search_button" class="btn btn-sm btn-default">Search</button></th>
</tr>
</thead>
<tbody>
<% decorate(@recipes, RecipeDecorator).each do |recipe| %>
<tr>
<td><%= link_to recipe.short_name, recipe %></td>
<td><%= recipe.tag_names %></td>
<td>
<% if recipe.rating %>
<%= text_field_tag('rating', recipe.rating, disabled: true, data: {rating: true, size: '20px', interval: '0.25'}) %>
<% else %>
--
<% end %>
</td>
<td><%= recipe.yields %></td>
<td><%= recipe_time(recipe) %></td>
<td><%= timestamp(recipe.created_at) %></td>
<td>
<% if current_user? %>
<%= link_to new_recipe_log_path(recipe), class: 'btn btn-sm btn-primary' do %>
<span class="glyphicon glyphicon-copy"></span>
<% end %>
<%= link_to edit_recipe_path(recipe), class: 'btn btn-sm btn-primary' do %>
<span class="glyphicon glyphicon-pencil"></span>
<% end %>
<%= link_to recipe, method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn btn-sm btn-danger' do %>
<span class="glyphicon glyphicon-remove"></span>
<% end %>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>
</div>
<% if @recipes.empty? %> <% if @recipes.empty? %>
<p>No Recipes</p> <p>No Recipes</p>
<% else %>
<% if current_user? %>
<%= link_to 'New Recipe', new_recipe_path, class: 'btn btn-default' %><br/>
<% end %>
<%= paginate @recipes %>
<div class="table-responsive">
<table class="recipe-table table table-striped table-hover">
<thead>
<tr>
<th><%= index_sort_header('Name', :name, @criteria) %></th>
<th>Tags</th>
<th><%= index_sort_header('Rating', :rating, @criteria) %></th>
<th>Yields</th>
<th><%= index_sort_header('Time', :total_time, @criteria) %></th>
<th><%= index_sort_header('Created', :created_at, @criteria) %></th>
<% if current_user? %>
<th></th>
<% end %>
</tr>
</thead>
<tbody>
<% decorate(@recipes, RecipeDecorator).each do |recipe| %>
<tr>
<td><%= link_to recipe.short_name, recipe %></td>
<td><%= recipe.tag_names %></td>
<td>
<% if recipe.rating %>
<%= text_field_tag('rating', recipe.rating, disabled: true, data: {rating: true, size: '20px', interval: '0.25'}) %>
<% else %>
--
<% end %>
</td>
<td><%= recipe.yields %></td>
<td><%= recipe_time(recipe) %></td>
<td><%= timestamp(recipe.created_at) %></td>
<% if current_user? %>
<td>
<%= link_to new_recipe_log_path(recipe), class: 'btn btn-sm btn-primary' do %>
<span class="glyphicon glyphicon-copy"></span>
<% end %>
<%= link_to edit_recipe_path(recipe), class: 'btn btn-sm btn-primary' do %>
<span class="glyphicon glyphicon-pencil"></span>
<% end %>
<%= link_to recipe, method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn btn-sm btn-danger' do %>
<span class="glyphicon glyphicon-remove"></span>
<% end %>
</td>
<% end %>
</tr>
<% end %>
</tbody>
</table>
</div>
<%= paginate @recipes %>
<% end %> <% end %>
<%= paginate @recipes %>
<br> <br>
<% if current_user? %> <% if current_user? %>
@ -76,4 +91,4 @@
<% end %> <% end %>
</div> </div>
</div> </div>