How can I use the method (helper) defined in a view in another view? - hanami

Let's say I have a form defined in View
module Admin
module Views
module Dashboard
class New
include Admin::View
def form
form_for :link, routes.links_path do
text_field :url
submit 'Create'
end
end
...
Am I missing something? since example below doesn't work:
module Admin
module Views
module Dashboard
class Index
include Admin::View
include Dashboard::New
...

You can't to share code from one view to another this way.
Your snippet does not work because Ruby does not allow to include classes in to another classes. So, if you want to do this - you should to use helper module. For your case it should looks like this:
module Admin
module Helpers
module Dashboard
def form
form_for :link, routes.links_path do
text_field :url
submit 'Create'
end
end
end
end
end
and include it in your view
module Admin
module Views
module Dashboard
class New
include Admin::View
include Admin::Helpers::Dashboard
# ...
end
end
end
end
or include it globally in your app
# apps/admin/application.rb
view.prepare do
include Hanami::Helpers
include Admin::Helpers::Dashboard
end
documentation: https://guides.hanamirb.org/helpers/custom-helpers/

Related

How can I use a datepicker in ActiveAdmin without rewriting the create form?

My ActiveAdmin model creation forms (ie. /admin/<model>/new) are using an awkward set of dropdowns for dates and datetimes.
I'd like to use pickers instead. But all the documentation I've found about using a datetime picker appears to require rewriting the whole form. There doesn't seem to be a way to change just one input, nor an equivalent of preserve_default_filters!.
I'd like to either change the default for all date and datetime columns, something like...
config.datepicker = ...
Or per column, like...
column :signed_up, as: :datetime_picker
EDIT
By default I get new and edit forms equivalent to this.
form do |f|
f.semantic_errors
f.inputs
f.actions
end
If I want to change signed_up to use a datepicker, I have to repeat all the columns supplied by default just to change the input type of one column.
ActiveAdmin.register Thing do
form do |f|
t.semantic_errors
t.input :name
t.input :this
t.input :that
t.input :signed_up, as: :datepicker
t.input :other
t.input :thing
t.input :left
t.input :right
t.actions
end
end
That's a lot of unnecessary repetition, and the formatting doesn't come out right. I'm looking for a way to change the input presentation of one column, or one type, without having to manually write the whole form every time.
Try the DateNTimePickerActiveAdmin Rubygem. It works really well and is customisable according to your project.
You can find the documentation here: https://github.com/NikhithaGraceJosh/date_n_time_picker_activeadmin
From the docs:
Gemfile
gem 'date_n_time_picker_activeadmin'
Code Sample (In your form)
f.input :column_name, as: :datetimepicker
CSS
In active_admin.scss, add the line,
#import date_n_time_picker_activeadmin
JS
In active_admin.js, add the line,
//= require date_n_time_picker_activeadmin
Hope it's useful!
I managed to monkey patch Active Admin behavior, to use :datepicker instead of :date_select.
In your config/application.rb, add following patches
Bundler.require(*Rails.groups)
// Start patch
module ActiveAdminFormBuilderPatch
def default_input_type(*_args, **_kwargs)
ret = super
ret == :date_select ? :datepicker : ret
end
end
ActiveAdmin::FormBuilder.include ActiveAdminFormBuilderPatch
// end patch
module YourApp
class Application < Rails::Application
// configs
end
end
Note
Confirmed this to be working on activeadmin version 2.9.0.
I used activeadmin_addons which does a lot of useful things, including using DateTimePicker for input, but not filters.
To get filters I use active_admin_datetimepicker which makes jQuery DateTimePicker available for inputs (:date_time_picker) and filters (:date_time_range). Then I monkey patched ActiveAdmin to use it by default.
# config/initializers/active_admin.rb
# Make the default filter type for a DateTime to be the DateTimeRange picker.
class ActiveAdmin::Filters::FormBuilder
protected
alias_method :original_default_input_type, :default_input_type
def default_input_type(method, options = {})
case column_for(method)&.type
when :datetime
return :date_time_range
end
original_default_input_type(method, options)
end
end

Redmine: extend controller action in plugin

Need some help in plugin development.
I've created hook in user/edit form view, added ballance_amount to form and have "ballance_amount"=>"1".
How can I extend default update action in user controller?
In base.class_eval do I've added alias_method_chain :update, :ballance
In InstanceMethods:
def update_with_ballance
ballance.amount = params[:user][:ballance_amount].to_f #I have ballance association
end
And get this:
NameError (undefined local variable or method `params' for #<User:0x007f972e9379d0>):
app/controllers/users_controller.rb:144:in `update'
How can I fetch params?
You should be able to make use of the mass-assignment code in the Redmine itself. Line 135 in the UsersController should handle provide you with a simple entry point for your extension, if balance_amount is considered a safe_attribute. To achieve that, add a patch like the following to the User model:
module RedmineBalancePlugin::UserPatch
def self.included(base)
base.class_eval do
safe_attributes 'balance_amount'
include InstanceMethods
end
end
module InstanceMethods
# This method is indirectly called when creating or updating a User
def balance_amount=(amount)
balance.amount = amount
end
# This could be useful in your view patch, but maybe not
def balance_amount
balance.amount
end
end
end
User.send(:include, RedmineBalancePlugin::UserPatch)
If this example does not help, it would be helpful, if you could provide more code fragments - e.g. the complete patch to the UsersController, to make it easier to reproduce and analyse the issue.

rails active record object in application controller

I'm adding a site-wide form for asking questions on a rails site. The models/views/controllers for the resource question are already created. Going to question/new shows the form as you'd expect. Now I want to display a site-wide question form (the only difference with this one is that it only shows mandatory fields). Question: should I create a new question object in application_controller and pass that to the rails form_for helper, or should I create a new _form2 partial(in the question view) and just include that in my site-wide template?
Thank you.
Create a question_form partial in the views/shared folder, and reference that from the site wide template.
Edit: in reply to where to get the #question variable from
You have two options in my mind, you can load the variable in ApplicationController:
class ApplicationController < ActionController::Base
before_filter :load_question
def load_question
#question = Question.new
end
...
end
(You should be careful of conflicts with the #question variable in this case)
Or probably better, you can create a method in ApplicationHelper:
module ApplicationHelper
def question_form
question = Question.new
raw render 'shared/question_form', :question => question
end
...
end
Then in your view, instead of referencing the partial, you reference the helper:
<%= question_form %>
In this case you would need to reference the variable in the partial as a local variable, so question instead of #question.
Hope that helps.

Rails - include module into controller, to be used in the view

I'm really new to Rails and I try to setup a module file to be used in the view. So I believe the correct behavior is to define the module as a helper within a controller and voila, it should be working. However, that's not the case for me. Here is the structure.
lib
functions
-- form_manager.rb
form_manager.rb:
Module Functions
Module FormManager
def error_message() ...
end
end
end
users_controller.rb
class UsersController < ApplicationController
helper FormManager
def new ...
Well, the structure is like the above and when I call the error_message from new.html.erb it gives me the error: uninitialized constant UsersController::FormManager.
So, first of all, I know that in rails 3 lib is not automatically loaded. Assuming that it is not mandatory to autoload the lib folder, how can I make this work and what am I missing?
BTW, please don't say that this question is duplicate. I'm telling you I've been searching for this crap for almost 2 days.
Your module is not autoloaded (at least not in 3.2.6). You have to load it explicitly. You can achieve this with the following line of code
# in application.rb
config.autoload_paths += %W(#{config.root}/lib)
You can check your autoload paths with Rails.application.config.autoload_paths. Maybe it's indeed defined for you?
Now you're sure your module gets loaded, you can check it in rails console by calling
> Functions::FormHelper
Now you can't use that module as a view helper by default. Use #included to define the helper when your module gets included. You achieve "lazy evaluation" this way. I think the problem with your code is that the helper method gets called before the module gets included. (somebody should correct me if I'm wrong)
Here's the code:
Module Functions
Module FormManager
def error_message() ...
end
def self.included m
return unless m < ActionController::Base
m.helper_method :error_message
end
end
end
You should also remove the helper line from your controller.
EDIT:
You can achieve this without autoloading. Just use require "functions/form_manager". You define a helper_method for every method. If you wish use all the module methods as helpers use
def self.included m
return unless m < ActionController::Base
m.helper_method self.instance_methods
end
EDIT2:
It appears that you don't need to use self.included. This achieves the same functionality:
class ApplicationController < ActionController::Base
include Functions::FormManager
helper_method Functions::FormManager.instance_methods
end
It appears you are namespacing FormManager inside of Functions which means you would call it by helper Functions::FormManager
Try that

before_filter not inheriting from parent controller correctly?

Sorry if this may be a stupid question but I'm unable get my filters to inherit the way the Rails 3 documentation is saying it should.
Specifically I have an Admin controller that was generated via:
rails generate controller admin
I added only a single action to the admin controller, the before filter & the private filter method
class AdminController < ApplicationController
before_filter require_admin_creds
def index
end
private
def require_admin_creds
unless current_user && current_user.admin?
flash[:error] = ...
redirect_to ....
end
end
end
I next then created my nested resources under the admin section with:
rails generate scaffold admin/model
While my admin index is indeed getting the filter, the admin/model index (or any other actions) are not. What is happening under the hood here that I must have excluded?
Thanks in advance.
Make require_admin_creds a protected method, not private.
Did you change:
Admin::ModelController < ApplicationController
to
Admin::ModelController < AdminController
?
This creates the inheritance, not placing the model controller into the admin namespace.
Double-check your syntax. You have:
before_filter require_admin_creds
but I think that should be:
before_filter :require_admin_creds
where you use a symbol, rather than a variable/method name.