Rendering an ERB template with a presenter - ruby

I am trying to render a .txt.erb file which uses a presenter to display values. The following code is inside ConfigurationWorker which is perfomed by resque:
#configuration = Configuration.first
#view = Rails.root.join 'lib', 'templates', 'config.txt.erb'
ERB.new(File.read(#view)).result(binding)
The config.txt.erb looks like this (shortened for simplicity):
<% present #configuration do |presenter| %>
Name <%= presenter.name %>
<% end %>
Whereas present is provided by ApplicationHelper and ConfigurationPresenter.
module ApplicationHelper
def present(object, klass = nil)
klass ||= "#{object.class}Presenter".constantize
presenter = klass.new(object, self)
yield presenter if block_given?
return presenter
end
end
class ConfigurationPresenter < ApplicationPresenter
presents :configuration
delegate :name, :configuration
# Presenter methods omitted
end
class ApplicationPresenter
def initialize(object, template)
#object = object
#template = template
end
def self.presents(name)
define_method(name) do
#object
end
end
def method_missing(*args, &block)
#template.send(*args, &block)
end
end
However, this results in NoMethodError: undefined method present for ConfigurationWorker:Class.
I also tried other approaches, like
#configuration = Configuration.first
renderer = ApplicationController.view_context_class.new
renderer.render :file => Rails.root.join('lib', 'templates', 'config.txt.erb')
which results in ActionView::Template::Error: uninitialized constant NilClassPresenter.
What is the proper way to make both the helper and the presenter available and pass in the variables?

Related

Puppet: Is it possible to call an instance method in a ruby template (era) that was returned from a custom function in a manifest?

There is a custom function that returns a class instance.
Puppet::Functions.create_function(:'my_custom_function') do
dispatch :make do
end
class Sample
attr_reader :value
def initialize( value )
#value = value
end
def to_s()
'<Sample %d>' % [ value ]
end
end
def make()
Sample.new(1)
end
end
ie:
class myclass {
$data = my_custom_function()
}
Is it possible to use the $data as a complex type in an ERB template?
Due to the "to_s" defined for the class this works:
<%= #data %>
yields
<Sample 1>
but it doesn't appear possible to access any of the instance methods (ie: #data.value)
When trying to access .value, the following error is typical:
Detail: undefined method `value' for #<Puppet::Pops::Loader::RubyFunctionInstantiator::Sample:0x7ace1824>
Is accessing class methods at all possible? If so, how?
Thanks.

How to access 'layout' of parent controller?

In one of my controllers I want to change the layout given some condition, and otherwise keep the default layout used by the parent ApplicationController (was "application" initially, but I'm trying some others now). Tried accessing the "layout" using alias_method but it doesn't seem to work. My code:
class SomeController < ApplicationController
alias_method :parent_layout, :layout
layout :some_layout
def some_layout
if some_condition
"new_layout"
else
:parent_layout
end
end
end
This gives an error:
ActionController::RoutingError (undefined method `layout' for class `SomeController'):
app/controllers/some_controller.rb:6:in `alias_method'
app/controllers/some_controller.rb:6:in `<class:SomeController>'
app/controllers/some_controller.rb:3:in `<top (required)>'
It looks like you have a bunch of options. Check out the docs here (search for "finding layouts")
http://guides.rubyonrails.org/layouts_and_rendering.html
Some possibilities, depending on just how complex you need it to be:
# Proc-based
class ProductsController < ApplicationController
layout Proc.new { |controller| controller.request.xhr? ? "popup" : "application" }
end
# Route based, :except and :only
class ProductsController < ApplicationController
layout "product", except: [:index, :rss]
end
# Method-based
class OldArticlesController < SpecialArticlesController
layout false
def show
#article = Article.find(params[:id])
end
def index
#old_articles = Article.older
render layout: "old"
end
# ...
end
I'm not sure how your code is structured but it looks like the first could work for you:
class SomeController < ApplicationController
layout Proc.new { |controller| controller.some_condition? ? "new_layout" : "application" }
end

NoMethodError in Posts#show ;

i have been learning rails through
http://guides.rubyonrails.org/getting_started.html.
I came across a error while performing save data in controller. The error that comes up when running the blog is :-undefined method `title' for nil:NilClass
**
My code for posts_controller.rb is
**
class PostsController < ApplicationController
def new
end
def create
#post=Post.new(params[:post].permit(:title,:text))
#post.save
redirect_to #post
end
private
def post_params
params.require(:post).permit(:title,:text)
end
def show
#post=Post.find(params[:id])
end
end
**
My code for show.html.rb is
**
<p>
<strong> Title:</strong>
<%= #post.title %>
</p>
<p>
<strong> Text:</strong>
<%= #post.text %>
</p>
**
The code for create_posts.rb
**
class CreatePosts < ActiveRecord::Migration
def change
create_table :posts do |t|
t.string :title
t.text :text
t.timestamps
end
end
Please help me out why this error is coming up when I have defined title in create_posts.
All methods defined after private are accessible only internally. Move the show method above private. And make sure you have a file called app/views/posts/show.html.erb and not .rb
Good luck!
# Make sure that you trying to access show method before the declaration of private as we can't access private methods outside of the class.
def show
#post = Post.find(params[:id])
end
def index
#posts = Post.all
end
def update
#post = Post.find(params[:id])
if #post.update(params[:post].permit(:title, :text))
redirect_to #post
else
render 'edit'
end
end
private
def post_params
params.require(:post).permit(:title, :text)
end
end
//vKj

Using Ability class in Rails Engine

I have a engine inside the lib folder named Support. In that folder, I have a Ticket controller.
I have created an ability class in the main app and I'm trying to manage all the models for the admin role. When I call the Tickets controller, it throws the error:
NameError in Support::TicketsController#index uninitialized constant Ticket
The app/model/ability.rb file is:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new
if user.role? == :admin
can :manage , :all
end
end
end
The lib/support/tickets_controller.rb file is:
module Support
class TicketsController < Support::ApplicationController
load_and_authorize_resource
respond_to :html, :xml, :json
def index
end
end
end
If the model class is namespaced differently than the controller, you will need to specify the :class option.
module Support
class TicketsController < ApplicationController
load_and_authorize_resource :class => Support::Ticket
end
end

How to set a default value based on the current_user?

I would like to set a default value based on the User creating it and I wonder how to do that:
class Item < ActiveRecord::Base
belongs_to :invoice
after_initialize :default_values
...
private
def default_values
self.tax_rate = current_user.tax_rate || 0
end
end
The problem is that I can't use the current_user inside the model.
This is what I've got in my controller:
def create
#invoice = Invoice.new(params[:invoice])
3.times { #invoice.items.build }
...
end
Can anybody help?
You can pass attributes to the build method, so you can remove the after_initialize ed edit the controller:
def create
#invoice = Invoice.new(params[:invoice])
3.times { #invoice.items.build( :tax_rate => current_user.tax_rate }
...
end

Resources