I'm trying to set my own controller for a page_layout, because I want to override the actions to get other models into the view.
Edit: frontend rendering works now. Only backend is buggy
From the docs, i did:
# config/alchemy/page_layouts.yml
- name: index
unique: true
elements: [article, other_element]
autogenerate: [article]
controller: 'my_custom'
action: 'index'
and created a app/controllers/my_custom_controller.rb
:
# app/controllers/my_custom_controller.rb
class MyCustomController < Alchemy::PagesController
def index
@some_values = Value.all
end
end
my routes.rb lookes like this:
Rails.application.routes.draw do
root 'my_custom#index'
devise_for :users,
path_names: { sign_in: 'login', sign_out: 'logout' },
controllers: { sessions: 'users/sessions', passwords: 'users/passwords' }
mount Alchemy::Engine => '/'
The root-page has the page_type index in alchemy.
And when i go to localhost:3000
I get what I want
But in the alchemy backend, when editing the page, i get an error when rendering:
NoMethodError in Alchemy::Admin::Pages#show
Showing app/views/alchemy/elements/_some_element_view.html.erb where line #2 raised:
undefined method `each' for nil:NilClass
Extracted source (around line #2):
<div class="row">
<% for @value in @some_values %>
<%= render 'value/basic_view' %>
<% end %>
</div>
probably, because the @some_values are not initialized, what would mean, that my controller wasn't used to render this. Am I doing something wrong?
Edit2: Maybe I'm on the complete wrong track. I want to have an Alchemy-Element, that renders stuff from the database (custom models). What I did is, creating an element, that renders the @some_values. And by specifing my custom controller on every page-type where this element can be placed on, I allow my editors to place those @some_values where they want.
It looks like this is not the right approach for what you want. Custom controllers for page layouts was introduced for routing reasons. So that editors can manage the navigation for custom controllers. They are not meant for decorating the default element and page rendering.
What you probably want is a on_page_layout
callback: http://www.rubydoc.info/github/AlchemyCMS/alchemy_cms/Alchemy/OnPageLayout
In your case:
class ApplicationController < ActionController::Base
extend Alchemy::OnPageLayout
on_page_layout :foo do
@some_values = Value.all
end
end
Or, even easier, load the values inside the the element view. A little PHPish, but also ok.
EDIT:
From a performance perspective using low level rails cache in your controller is a good practice:
...
on_page_layout :foo do
@some_values = Rails.cache.fetch('some/cache/key', expires_in: 10.minutes) do
Value.all
end
end
...