Skip to content

Commit

Permalink
Implement model name wrapper class
Browse files Browse the repository at this point in the history
  • Loading branch information
spohlenz committed Sep 20, 2017
1 parent c6621cb commit 2ffe019
Show file tree
Hide file tree
Showing 12 changed files with 111 additions and 59 deletions.
2 changes: 1 addition & 1 deletion app/views/trestle/resource/edit.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<% title = t("admin.titles.edit", default: "Editing %{model_name}", model_name: admin.model_name, pluralized_model_name: admin.model_name.pluralize) %>
<% title = t("admin.titles.edit", default: "Editing %{model_name}", model_name: admin.model_name.titleize, pluralized_model_name: admin.model_name.plural.titleize) %>
<% content_for(:title, title) %>
<% breadcrumb title %>
Expand Down
2 changes: 1 addition & 1 deletion app/views/trestle/resource/index.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<% content_for(:title, t("admin.titles.index", default: "Listing %{pluralized_model_name}", model_name: admin.model_name, pluralized_model_name: admin.model_name.pluralize)) %>
<% content_for(:title, t("admin.titles.index", default: "Listing %{pluralized_model_name}", model_name: admin.model_name.titleize, pluralized_model_name: admin.model_name.plural.titleize)) %>
<% content_for(:primary_toolbar) do %>
<%= link_to admin.path(:new), class: "btn btn-default btn-lg" do %>
Expand Down
2 changes: 1 addition & 1 deletion app/views/trestle/resource/new.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<% title = t("admin.titles.new", default: "New %{model_name}", model_name: admin.model_name, pluralized_model_name: admin.model_name.pluralize) %>
<% title = t("admin.titles.new", default: "New %{model_name}", model_name: admin.model_name.titleize, pluralized_model_name: admin.model_name.plural.titleize) %>
<% content_for(:title, title) %>
<% breadcrumb title %>
Expand Down
2 changes: 1 addition & 1 deletion app/views/trestle/resource/show.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<% title = t("admin.titles.edit", default: "Editing %{model_name}", model_name: admin.model_name, pluralized_model_name: admin.model_name.pluralize) %>
<% title = t("admin.titles.edit", default: "Editing %{model_name}", model_name: admin.model_name.titleize, pluralized_model_name: admin.model_name.plural.titleize) %>
<% content_for(:title, title) %>
<% breadcrumb title %>
Expand Down
8 changes: 4 additions & 4 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ en:
flash:
success:
title: "Success!"
create: "The %{model_name} was successfully created."
update: "The %{model_name} was successfully updated."
destroy: "The %{model_name} was successfully deleted."
create: "The %{lowercase_model_name} was successfully created."
update: "The %{lowercase_model_name} was successfully updated."
destroy: "The %{lowercase_model_name} was successfully deleted."

failure:
title: "Warning!"
create: "Please correct the errors below."
update: "Please correct the errors below."
destroy: "Could not delete %{model_name}."
destroy: "Could not delete %{lowercase_model_name}."

helpers:
page_entries_info:
Expand Down
1 change: 1 addition & 0 deletions lib/trestle.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ module Trestle
autoload :Configuration
autoload :Display
autoload :Form
autoload :ModelName
autoload :Navigation
autoload :Options
autoload :Reloader
Expand Down
45 changes: 45 additions & 0 deletions lib/trestle/model_name.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
require "active_model/naming"

module Trestle
class ModelName
attr_reader :klass

delegate :downcase, :upcase, :titleize, :titlecase, to: :to_s

def initialize(klass)
@klass = klass

if klass.respond_to?(:model_name)
@name = klass.model_name
else
@name = ActiveModel::Name.new(klass)
end
end

def ==(other)
other.is_a?(self.class) && klass == other.klass
end

def to_s
human
end

def singular(options={})
human(options)
end
alias_method :singularize, :singular

def plural(options={})
if klass.respond_to?(:lookup_ancestors) && klass.respond_to?(:i18n_scope)
human({ count: :many, default: human.pluralize }.merge(options))
else
human.pluralize
end
end
alias_method :pluralize, :plural

def human(options={})
@name.human(options)
end
end
end
13 changes: 2 additions & 11 deletions lib/trestle/resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -119,15 +119,15 @@ def model
end

def model_name
options[:as] || default_model_name
@model_name ||= Trestle::ModelName.new(model)
end

def readonly?
options[:readonly]
end

def breadcrumb
Breadcrumb.new(model_name.pluralize, path)
Breadcrumb.new(model_name.plural.titleize, path)
end

def routes
Expand All @@ -150,15 +150,6 @@ def infer_model_class
rescue NameError
raise NameError, "Unable to find model #{admin_name.classify}. Specify a different model using Trestle.resource(:#{admin_name}, model: MyModel)"
end

def default_model_name
if model.respond_to?(:model_name)
model_name = model.model_name
model_name.respond_to?(:human) ? model_name.human : model_name.to_s.titleize
else
model.name.titleize
end
end
end
end
end
10 changes: 5 additions & 5 deletions lib/trestle/resource/controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def create
if admin.save_instance(instance)
respond_to do |format|
format.html do
flash[:message] = flash_message("success.create", default: "The %{model_name} was successfully created.")
flash[:message] = flash_message("success.create", default: "The %{lowercase_model_name} was successfully created.")
redirect_to action: :show, id: admin.to_param(instance)
end
format.json { render json: instance, status: :created, location: { action: :show, id: admin.to_param(instance) } }
Expand Down Expand Up @@ -62,7 +62,7 @@ def update
if admin.save_instance(instance)
respond_to do |format|
format.html do
flash[:message] = flash_message("success.update", default: "The %{model_name} was successfully updated.")
flash[:message] = flash_message("success.update", default: "The %{lowercase_model_name} was successfully updated.")
redirect_to action: :show, id: admin.to_param(instance)
end
format.json { render json: instance, status: :ok }
Expand All @@ -86,10 +86,10 @@ def destroy
respond_to do |format|
format.html do
if success
flash[:message] = flash_message("success.destroy", default: "The %{model_name} was successfully deleted.")
flash[:message] = flash_message("success.destroy", default: "The %{lowercase_model_name} was successfully deleted.")
redirect_to action: :index
else
flash[:error] = flash_message("failure.destroy", default: "Could not delete %{model_name}.")
flash[:error] = flash_message("failure.destroy", default: "Could not delete %{lowercase_model_name}.")

if self.instance = admin.find_instance(params)
redirect_to action: :show, id: admin.to_param(instance)
Expand All @@ -111,7 +111,7 @@ def destroy
helper_method :instance

def flash_message(type, options={})
t("trestle.flash.#{type}", options.merge(model_name: admin.model_name.underscore.humanize(capitalize: false)))
t("trestle.flash.#{type}", options.merge(model_name: admin.model_name, lowercase_model_name: admin.model_name.downcase))
end
end
end
Expand Down
45 changes: 45 additions & 0 deletions spec/trestle/model_name_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
require 'spec_helper'

describe Trestle::ModelName do
let(:klass) { stub_const("TestPost", Class.new(ActiveRecord::Base)) }
subject(:name) { Trestle::ModelName.new(klass) }

it "converts to string" do
expect(name.to_s).to eq("Test post")
end

it "delegates string methods to to_s" do
expect(name.downcase).to eq("test post")
expect(name.upcase).to eq("TEST POST")
expect(name.titleize).to eq("Test Post")
expect(name.titlecase).to eq("Test Post")
end

it "has a singular form" do
expect(name.singular).to eq("Test post")
expect(name.singularize).to eq("Test post")
expect(name.human).to eq("Test post")
end

it "has a plural form" do
expect(name.plural).to eq("Test posts")
expect(name.pluralize).to eq("Test posts")
end

it "is equal to another ModelName with the same class" do
expect(name).to eq(Trestle::ModelName.new(klass))
expect(name).not_to eq(Trestle::ModelName.new(String))
end

context "plain ruby class" do
let(:klass) { stub_const("Article", Class.new) }

it "has a singular form" do
expect(name.singular).to eq("Article")
end

it "has a plural form" do
expect(name.plural).to eq("Articles")
end
end
end
39 changes: 4 additions & 35 deletions spec/trestle/resource_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ class AlternateModel; end
expect(admin.model).to eq(AlternateModel)
end

it "has a model name" do
expect(admin.model_name).to eq(Trestle::ModelName.new(Test))
end

it "has a breadcrumb trail" do
trail = Trestle::Breadcrumb::Trail.new([
Trestle::Breadcrumb.new("Home", "/admin"),
Expand Down Expand Up @@ -83,41 +87,6 @@ class Test; end
expect(admin.decorate_collection(collection)).to eq(collection)
end

describe "#model_name" do
before(:each) do
class Test; end
end

context "#model_name on the class returns an ActiveModel::Name" do
it "returns the humanized model name" do
model_name = double(human: "ActiveModel Class")

expect(Test).to receive(:model_name).and_return(model_name)
expect(admin.model_name).to eq("ActiveModel Class")
end
end

context "#model_name on the class returns a string" do
it "returns the titleized model name" do
expect(Test).to receive(:model_name).and_return("TestClass")
expect(admin.model_name).to eq("Test Class")
end
end

context "#model_name is not defined on the class" do
it "returns the titleized class name" do
expect(admin.model_name).to eq("Test")
end
end

it "can be overridden via the `as` option" do
admin.options = { as: "Custom Class" }

expect(Test).to_not receive(:model_name)
expect(admin.model_name).to eq("Custom Class")
end
end

describe "#apply_sorting" do
let(:collection) { double }
let(:sorted_collection) { double }
Expand Down
1 change: 1 addition & 0 deletions trestle.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Gem::Specification.new do |spec|
spec.required_ruby_version = ">= 2.2.2"

spec.add_dependency "railties", ">= 4.2.0"
spec.add_dependency "activemodel", ">= 4.2.0"
spec.add_dependency "sass-rails", "~> 5.0.6"
spec.add_dependency "autoprefixer-rails", "~> 7.1.2"
spec.add_dependency "kaminari", "~> 1.0.1"
Expand Down

0 comments on commit 2ffe019

Please sign in to comment.