Skip to content

Commit

Permalink
Allow to limit route actions
Browse files Browse the repository at this point in the history
This allows to limit route actions such as :index and :show in routes.rb
and only display these routes in views.
  • Loading branch information
infertux authored and nickcharlton committed Mar 7, 2017
1 parent 969a062 commit 4ac1521
Show file tree
Hide file tree
Showing 20 changed files with 168 additions and 42 deletions.
8 changes: 5 additions & 3 deletions app/assets/javascripts/administrate/components/table.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ $(function() {
var keycodes = { space: 32, enter: 13 };

var visitDataUrl = function(event) {
if (event.type=="click" ||
if (event.type == "click" ||
event.keyCode == keycodes.space ||
event.keyCode == keycodes.enter) {

if(!event.target.href) {
window.location = $(event.target).closest("tr").data("url");
if (!event.target.href) {
var url = $(event.target).closest("tr").data("url");

if (url) { window.location = url; }
}
}
};
Expand Down
11 changes: 11 additions & 0 deletions app/controllers/administrate/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,17 @@ def nav_link_state(resource)
end
end

helper_method :valid_action?
def valid_action?(name, resource = resource_name)
!!routes.detect do |controller, action|
controller == resource.to_s.pluralize && action == name.to_s
end
end

def routes
@routes ||= Namespace.new(namespace).routes
end

def records_per_page
params[:per_page] || 20
end
Expand Down
35 changes: 20 additions & 15 deletions app/views/administrate/application/_collection.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,17 @@ to display a collection of resources in an HTML table.
<% end %>
</th>
<% end %>
<th colspan="2" scope="col"></th>
<% [valid_action?(:edit), valid_action?(:destroy)].count(true).times do %>
<th scope="col"></th>
<% end %>
</tr>
</thead>

<tbody>
<% resources.each do |resource| %>
<tr class="table__row"
role="link"
tabindex="0"
data-url="<%= polymorphic_path([namespace, resource]) -%>"
<%= %(role=link data-url=#{polymorphic_path([namespace, resource])}) if valid_action? :show -%>
>
<% collection_presenter.attributes_for(resource).each do |attribute| %>
<td class="cell-data cell-data--<%= attribute.html_class %>">
Expand All @@ -68,19 +69,23 @@ to display a collection of resources in an HTML table.
</td>
<% end %>

<td><%= link_to(
t("administrate.actions.edit"),
[:edit, namespace, resource],
class: "action-edit",
) %></td>
<% if valid_action? :edit %>
<td><%= link_to(
t("administrate.actions.edit"),
[:edit, namespace, resource],
class: "action-edit",
) %></td>
<% end %>

<td><%= link_to(
t("administrate.actions.destroy"),
[namespace, resource],
class: "table__action--destroy",
method: :delete,
data: { confirm: t("administrate.actions.confirm") }
) %></td>
<% if valid_action? :destroy %>
<td><%= link_to(
t("administrate.actions.destroy"),
[namespace, resource],
class: "table__action--destroy",
method: :delete,
data: { confirm: t("administrate.actions.confirm") }
) %></td>
<% end %>
</tr>
<% end %>
</tbody>
Expand Down
2 changes: 1 addition & 1 deletion app/views/administrate/application/edit.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ It displays a header, and renders the `_form` partial to do the heavy lifting.
"Show #{page.page_title}",
[namespace, page.resource],
class: "button",
) %>
) if valid_action? :show %>
</div>
</header>

Expand Down
2 changes: 1 addition & 1 deletion app/views/administrate/application/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ It renders the `_table` partial to display details about the resources.
"New #{page.resource_name.titleize.downcase}",
[:new, namespace, page.resource_name],
class: "button",
) %>
) if valid_action? :new %>
</div>
</header>

Expand Down
2 changes: 1 addition & 1 deletion app/views/administrate/application/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ as well as a link to its edit page.
"Edit",
[:edit, namespace, page.resource],
class: "button",
) %>
) if valid_action? :edit %>
</div>
</header>

Expand Down
12 changes: 8 additions & 4 deletions app/views/fields/belongs_to/_index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@ By default, the relationship is rendered as a link to the associated object.
%>

<% if field.data %>
<%= link_to(
field.display_associated_resource,
[namespace, field.data],
) %>
<% if valid_action?(:show, field.attribute) %>
<%= link_to(
field.display_associated_resource,
[namespace, field.data],
) %>
<% else %>
<%= field.display_associated_resource %>
<% end %>
<% end %>
12 changes: 8 additions & 4 deletions app/views/fields/belongs_to/_show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@ By default, the relationship is rendered as a link to the associated object.
%>

<% if field.data %>
<%= link_to(
field.display_associated_resource,
[namespace, field.data],
) %>
<% if valid_action?(:show, field.attribute) %>
<%= link_to(
field.display_associated_resource,
[namespace, field.data],
) %>
<% else %>
<%= field.display_associated_resource %>
<% end %>
<% end %>
20 changes: 10 additions & 10 deletions lib/administrate/namespace.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,24 @@ def initialize(namespace)
end

def resources
namespace_controller_paths.uniq.map do |controller|
controller.gsub(/^#{namespace}\//, "").to_sym
@resources ||= routes.map(&:first).uniq.map(&:to_sym)
end

def routes
@routes ||= all_routes.select do |controller, _action|
controller.starts_with?(namespace.to_s)
end.map do |controller, action|
[controller.gsub(/^#{namespace}\//, ""), action]
end
end

private

attr_reader :namespace

def namespace_controller_paths
all_controller_paths.select do |controller|
controller.starts_with?(namespace.to_s)
end
end

def all_controller_paths
def all_routes
Rails.application.routes.routes.map do |route|
route.defaults[:controller].to_s
route.defaults.values_at(:controller, :action).map(&:to_s)
end
end
end
Expand Down
4 changes: 4 additions & 0 deletions spec/example_app/app/controllers/admin/payments_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module Admin
class PaymentsController < Admin::ApplicationController
end
end
16 changes: 16 additions & 0 deletions spec/example_app/app/dashboards/payment_dashboard.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
require "administrate/base_dashboard"

class PaymentDashboard < Administrate::BaseDashboard
ATTRIBUTE_TYPES = {
id: Field::Number,
created_at: Field::DateTime,
updated_at: Field::DateTime,
order: Field::BelongsTo,
}

COLLECTION_ATTRIBUTES = [
:id,
]

SHOW_PAGE_ATTRIBUTES = ATTRIBUTE_TYPES.keys
end
3 changes: 3 additions & 0 deletions spec/example_app/app/models/payment.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class Payment < ActiveRecord::Base
belongs_to :order
end
1 change: 1 addition & 0 deletions spec/example_app/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
resources :line_items
resources :orders
resources :products
resources :payments, only: [:index, :show]

root to: "customers#index"
end
Expand Down
8 changes: 8 additions & 0 deletions spec/example_app/db/migrate/20160815100728_create_payments.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class CreatePayments < ActiveRecord::Migration
def change
create_table :payments do |t|
t.references :order, index: true
end
add_foreign_key :payments, :orders
end
end
9 changes: 8 additions & 1 deletion spec/example_app/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20160119024340) do
ActiveRecord::Schema.define(version: 20160815100728) do

# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
Expand Down Expand Up @@ -67,6 +67,12 @@

add_index "orders", ["customer_id"], name: "index_orders_on_customer_id", using: :btree

create_table "payments", force: :cascade do |t|
t.integer "order_id"
end

add_index "payments", ["order_id"], name: "index_payments_on_order_id", using: :btree

create_table "products", force: :cascade do |t|
t.string "name"
t.float "price"
Expand All @@ -82,4 +88,5 @@
add_foreign_key "line_items", "orders"
add_foreign_key "line_items", "products"
add_foreign_key "orders", "customers"
add_foreign_key "payments", "orders"
end
4 changes: 4 additions & 0 deletions spec/factories.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,8 @@
image_url \
"https://cdn.recombu.com/mobile/images/news/M11370/1264769196_w670.jpg"
end

factory :payment do
order
end
end
2 changes: 1 addition & 1 deletion spec/features/orders_index_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
order = create(:order)

visit admin_orders_path
click_on "Edit"
click_on t("administrate.actions.edit")

expect(current_path).to eq(edit_admin_order_path(order))
end
Expand Down
2 changes: 1 addition & 1 deletion spec/features/orders_show_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
require "rails_helper"

feature "order index page" do
feature "order show page" do
scenario "displays line item information" do
line_item = create(:line_item)

Expand Down
40 changes: 40 additions & 0 deletions spec/features/payments_index_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require "rails_helper"

feature "payment index page" do
scenario "user views payment attributes" do
payment = create(:payment)

visit admin_payments_path

expect(page).to have_header("Payments")
expect(page).to have_content(payment.id)
end

scenario "user clicks through to the payment show page", :js do
payment = create(:payment)

visit admin_payments_path
click_row_for(payment)

expect(page).to have_header(displayed(payment))
end

scenario "user cannot click through to the edit page" do
create(:payment)

visit admin_payments_path
expect(page).not_to have_button t("administrate.actions.edit")
end

scenario "user cannot click through to the new page" do
visit admin_payments_path
expect(page).not_to have_button "New payment"
end

scenario "user cannot delete record" do
create(:payment)

visit admin_payments_path
expect(page).not_to have_button t("administrate.actions.destroy")
end
end
17 changes: 17 additions & 0 deletions spec/features/payments_show_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
require "rails_helper"

feature "payment show page" do
scenario "user cannot click through to the edit page" do
payment = create(:payment)

visit admin_payment_path(payment)
expect(page).not_to have_button t("administrate.actions.edit")
end

scenario "user cannot delete record" do
payment = create(:payment)

visit admin_payment_path(payment)
expect(page).not_to have_button t("administrate.actions.destroy")
end
end

0 comments on commit 4ac1521

Please sign in to comment.