Skip to content

Commit 8ef9389

Browse files
committed
Add context to Page
1 parent 6fb318f commit 8ef9389

File tree

17 files changed

+248
-38
lines changed

17 files changed

+248
-38
lines changed

app/controllers/administrate/application_controller.rb

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ class ApplicationController < ActionController::Base
55
def index
66
authorize_resource(resource_class)
77
search_term = params[:search].to_s.strip
8-
resources = filter_resources(scoped_resource, search_term: search_term)
8+
authorized_scope = authorize_scope(scoped_resource)
9+
resources = filter_resources(authorized_scope, search_term: search_term)
910
resources = apply_collection_includes(resources)
1011
resources = order.apply(resources)
1112
resources = paginate_resources(resources)
1213
page = Administrate::Page::Collection.new(dashboard, order: order)
14+
page.context = self
1315

1416
render locals: {
1517
resources: resources,
@@ -20,28 +22,39 @@ def index
2022
end
2123

2224
def show
25+
page = Administrate::Page::Show.new(dashboard, requested_resource)
26+
page.context = self
2327
render locals: {
24-
page: Administrate::Page::Show.new(dashboard, requested_resource)
28+
page: page
2529
}
2630
end
2731

2832
def new
29-
resource = new_resource
30-
authorize_resource(resource)
33+
resource = new_resource.tap do |resource|
34+
authorize_resource(resource)
35+
contextualize_resource(resource)
36+
end
37+
38+
page = Administrate::Page::Form.new(dashboard, resource)
39+
page.context = self
3140
render locals: {
32-
page: Administrate::Page::Form.new(dashboard, resource)
41+
page: page
3342
}
3443
end
3544

3645
def edit
46+
page = Administrate::Page::Form.new(dashboard, requested_resource)
47+
page.context = self
3748
render locals: {
38-
page: Administrate::Page::Form.new(dashboard, requested_resource)
49+
page: page
3950
}
4051
end
4152

4253
def create
43-
resource = new_resource(resource_params)
44-
authorize_resource(resource)
54+
resource = new_resource(resource_params).tap do |resource|
55+
authorize_resource(resource)
56+
contextualize_resource(resource)
57+
end
4558

4659
if resource.save
4760
yield(resource) if block_given?
@@ -50,8 +63,10 @@ def create
5063
notice: translate_with_resource("create.success")
5164
)
5265
else
66+
page = Administrate::Page::Form.new(dashboard, resource)
67+
page.context = self
5368
render :new, locals: {
54-
page: Administrate::Page::Form.new(dashboard, resource)
69+
page: page
5570
}, status: :unprocessable_entity
5671
end
5772
end
@@ -64,8 +79,10 @@ def update
6479
status: :see_other
6580
)
6681
else
82+
page = Administrate::Page::Form.new(dashboard, requested_resource)
83+
page.context = self
6784
render :edit, locals: {
68-
page: Administrate::Page::Form.new(dashboard, requested_resource)
85+
page: page
6986
}, status: :unprocessable_entity
7087
end
7188
end
@@ -184,11 +201,16 @@ def dashboard
184201
def requested_resource
185202
@requested_resource ||= find_resource(params[:id]).tap do |resource|
186203
authorize_resource(resource)
204+
contextualize_resource(resource)
187205
end
188206
end
189207

190208
def find_resource(param)
191-
scoped_resource.find(param)
209+
authorize_scope(scoped_resource).find(param)
210+
end
211+
212+
def authorize_scope(scope)
213+
scope
192214
end
193215

194216
def scoped_resource
@@ -203,7 +225,7 @@ def apply_collection_includes(relation)
203225

204226
def resource_params
205227
params.require(resource_class.model_name.param_key)
206-
.permit(dashboard.permitted_attributes(action_name))
228+
.permit(dashboard.permitted_attributes(action_name, self))
207229
.transform_values { |v| read_param_value(v) }
208230
end
209231

@@ -285,6 +307,13 @@ def authorize_resource(resource)
285307
end
286308
end
287309

310+
# Override this if you want to contextualize the resource differently.
311+
#
312+
# @param resource A resource to be contextualized.
313+
# @return nothing
314+
def contextualize_resource(resource)
315+
end
316+
288317
def paginate_resources(resources)
289318
resources.page(params[:_page]).per(records_per_page)
290319
end

app/controllers/concerns/administrate/punditize.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ def policy_namespace
1515
[]
1616
end
1717

18-
def scoped_resource
19-
namespaced_scope = policy_namespace + [super]
18+
def authorize_scope(scope)
19+
namespaced_scope = policy_namespace + [scope]
2020
policy_scope!(pundit_user, namespaced_scope)
2121
end
2222

docs/customizing_controller_actions.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,17 @@ class Admin::FoosController < Admin::ApplicationController
4141
# resource_class.with_less_stuff
4242
# end
4343
# end
44+
45+
46+
# Override this if you want to contextualize the resource differently.
47+
# This will be used to contextualize the resource for the all actions without `index`.
48+
#
49+
# def contextualize_resource(resource)
50+
# case action_name
51+
# when "new", "create"
52+
# resource.author = current_user
53+
# end
54+
# end
4455
end
4556
```
4657

lib/administrate/base_dashboard.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def all_attributes
5151
attribute_types.keys
5252
end
5353

54-
def form_attributes(action = nil)
54+
def form_attributes(action = nil, _context = nil)
5555
action =
5656
case action
5757
when "update" then "edit"
@@ -69,8 +69,8 @@ def specific_form_attributes_for(action)
6969
self.class.const_get(cname) if self.class.const_defined?(cname)
7070
end
7171

72-
def permitted_attributes(action = nil)
73-
attributes = form_attributes action
72+
def permitted_attributes(action = nil, context = nil)
73+
attributes = form_attributes(action, context)
7474

7575
if attributes.is_a? Hash
7676
attributes = attributes.values.flatten

lib/administrate/field/belongs_to.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,12 @@ def include_blank_option
4141
private
4242

4343
def candidate_resources
44-
scope = options[:scope] ? options[:scope].call : associated_class.all
44+
scope =
45+
if options[:scope]
46+
options[:scope].call(self)
47+
else
48+
associated_class.all
49+
end
4550

4651
order = options.delete(:order)
4752
order ? scope.reorder(order) : scope

lib/administrate/page/base.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ def item_associations
2727
dashboard.try(:item_associations) || []
2828
end
2929

30+
attr_accessor :context
31+
3032
private
3133

3234
def attribute_field(dashboard, resource, attribute_name, page)

lib/administrate/page/form.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def initialize(dashboard, resource)
1111
attr_reader :resource
1212

1313
def attributes(action = nil)
14-
attributes = dashboard.form_attributes(action)
14+
attributes = dashboard.form_attributes(action, context)
1515

1616
if attributes.is_a? Array
1717
attributes = {"" => attributes}

spec/controllers/admin/customers_controller_spec.rb

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
describe Admin::CustomersController, type: :controller do
44
describe "GET index" do
55
it "passes all customers to the view" do
6-
customer = create(:customer)
6+
customers = create_list(:customer, 5)
77

88
locals = capture_view_locals { get :index }
9-
expect(locals[:resources]).to eq([customer])
9+
expect(locals[:resources]).to eq(customers)
1010
end
1111

1212
it "applies any scope overrides" do
@@ -47,6 +47,22 @@
4747
expect(locals[:resources].map(&:id)).to eq customers.map(&:id).sort
4848
end
4949

50+
context "when the user is an admin" do
51+
controller(Admin::CustomersController) do
52+
def authenticate_admin
53+
@current_user = Customer.last
54+
end
55+
end
56+
57+
it "passes one customers to the view" do
58+
_other_customers = create_list(:customer, 5)
59+
customer = create(:customer)
60+
61+
locals = capture_view_locals { get :index }
62+
expect(locals[:resources]).to eq([customer])
63+
end
64+
end
65+
5066
context "with alternate sorting attributes" do
5167
controller(Admin::CustomersController) do
5268
def default_sorting_attribute

spec/controllers/admin/orders_controller_spec.rb

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ def pundit_user
3434
end
3535

3636
describe "GET new" do
37-
it "raises a Pundit error" do
38-
expect { get :new }.to raise_error(Pundit::NotAuthorizedError)
37+
it "allows me to new my records" do
38+
expect { get :new }.not_to raise_error
3939
end
4040
end
4141

@@ -154,8 +154,8 @@ def pundit_user
154154
end
155155

156156
describe "GET new" do
157-
it "raises a Pundit error" do
158-
expect { get :new }.to raise_error(Pundit::NotAuthorizedError)
157+
it "allows me to new my records" do
158+
expect { get :new }.not_to raise_error
159159
end
160160
end
161161

@@ -233,6 +233,64 @@ def send_request(order:)
233233
expect(controller.send(:authorized_action?, o, :destroy)).to be false
234234
end
235235
end
236+
237+
context "when the user is an admin" do
238+
controller(Admin::OrdersController) do
239+
def pundit_user
240+
Struct.new(:admin?).new(true)
241+
end
242+
end
243+
244+
let!(:user) { create(:customer, name: "Target User") }
245+
246+
describe "GET new" do
247+
it "allows me to new my records" do
248+
expect { get :new }.not_to raise_error
249+
end
250+
end
251+
252+
describe "POST create" do
253+
it "allows me to create my records with target user" do
254+
post(
255+
:create,
256+
params: {
257+
order: attributes_for(:order, customer_id: user.id)
258+
}
259+
)
260+
expect(response).to redirect_to([:admin, (order = Order.last)])
261+
expect(order.customer).to eq(user)
262+
end
263+
end
264+
end
265+
end
266+
267+
context "when the user is not an admin" do
268+
controller(Admin::OrdersController) do
269+
def pundit_user
270+
Customer.find_by(name: "Current User")
271+
end
272+
end
273+
274+
let!(:user) { create(:customer, name: "Current User") }
275+
276+
describe "GET new" do
277+
it "allows me to new records" do
278+
expect { get :new }.not_to raise_error
279+
end
280+
end
281+
282+
describe "POST create" do
283+
it "allows me to create my records with current customer" do
284+
post(
285+
:create,
286+
params: {
287+
order: attributes_for(:order)
288+
}
289+
)
290+
expect(response).to redirect_to([:admin, (order = Order.last)])
291+
expect(order.customer).to eq(user)
292+
end
293+
end
236294
end
237295
end
238296
# standard:enable Lint/ConstantDefinitionInBlock

0 commit comments

Comments
 (0)