ruby on rails Controller class instantiate a ruby class? - ruby-on-rails

I am new to RoR .I want my controller to instatiate an existing class from lib .
Collect data in the form of a string and throw the result on the view.erb.Can I do that.
Do i have to create a new model object and that should that model object inturn call the lib class.

Not really sure what you want to do.
If you used a library class - a module for example - its automatically instantiated, when you use 'include'
If you just have a generic class, and you included it somewhere, then you already have the class object loaded and can call methods on it. Or you just create an instance manually with 'object = new MyClass'.
And then call whatever you like on 'object'.
Whatever Information you collect inside the controller method, you can access in the view, when you place an '#'-Symbol before your variable.
So if you want your show.html.erb look like this:
<h1>My String:</h1>
<%= #mystring %>
then you have to do something like this in your controller:
def show
...
#mystring = MyClass.get_my_cool_string
...
end
Hope that helps...

Related

How to Fix "Attempted to call an undefined method named "createNamedBuilder..."?

I'm trying to create a named form (builder) within my controller like
...
$form = $this->createNamedBuilder('form1', $data)
->add(...)
->getForm();
But i get the title-mentioned error.
When i check the abstract controller trait class there are no createNamed() or createNamedBuilder() functions in there.
How do i create a named form with a form builder?
Kind Regards
According to This you need to acquire the FormFactory(Interface via Dependency Injection).
Adding FormFactoryInterface $formFactory to my controller method's parameters and using it like
$formFactory->createNamedBuilder('name', FormType::class, $data)...
did the trick.

Rails4 Access controller_name from model method

I have user role based access control. User has many roles.
Each role has access to some controllers, actions and scopes.
I have method can_control?(controller) in User model which check if user have access to specific controller. I have similar method to actions.
Then in view or controller I can make simple logic to hide some information or permit access using:
current_user.can_control?(controller_name)
I wonder if it possible to create method in User model which automatically takes controller_name. I tried to define method in model.
def can_control?
self.permitted_cotrollers.include?(controller_name)
end
But it gives me an error:
undefined local variable or method `controller_name' for #<User:0x007f00e8ceb928>
I understand error, but can find solution or if it possible to have one.
Here is the best solution I can think of : You can access the current controller name in params[:controller] from any controller method.
In User model :
def can_control?(params)
self.permitted_controllers.include?(params[:controller])
end
In any controller :
current_user.can_control?(params)
In your model, you can get the standard associated controller name by using :
"#{self.class.to_s}Controller"
self refers to your model
.class gets its class
.to_s converts its class to a string containing its class name
If you need it written in snake_case instead of CamelCase, use this :
"#{self.class.to_s.tableize}_controller"
.tableize converts the CamelCase name of your model into the snake_case name used in your controller

Passing a URL to code in a helper method.

I created a Foo controller, and the Foo view allows users to enter and submit a URL. In my Foo helper I have a block of code which scrapes the URL entered by the user (Using nokogiri). How do I pass the url received from the user to the helper so that URL can be parsed and saved to the db? Should I set this up differently?
One way to archive this in Rails 3 is to call view_context inside the
controller to create a new ActionView instance for a controller, then
all helper methods will be available through this instance in the
controller.
view_context.scrape_url_method_in_helper
Or do this in FooController
include FooHelper
Also, read rik.vanmechelen's comment below.

How to call a Grails service in a view?

Simple question :
I have a service class (let's say helpersService) and a method def constructURI(params).
How can I call this method from a template view.
I have tried the following code without success
<% def helpersService = new HelpersService() // or def helpersService
%>
<img src="${helpersService. constructURI(params)}"/>
But I get the following result:
No signature of method: com.HelpersService. constructURI() is applicable for argument types...
or (in case I use def helpersService)
Cannot invoke method constructURI() on null object
Any ideas?
Services are not intended to be used inside views. You could create a TagLib where you can get a reference to the service via dependency injection.
An easier method, assuming your view is being rendered by a Controller, is to just pass a reference to the service from the action to the view within the model, i.e.:
class someController {
def someService
def someAction = {
render(view: 'someView', model: ['someService': someService])
}
}
It can then be used as you would expect within the view. For a template rendered by a view, obviously you need to pass the reference to the template as well. Just to be clear though, S. Puchbauer is right; services are not really supposed to be used within Views, and you may experience difficult to diagnose problems, especially related to transactions and the Hibernate session.
I found out, that this groovy inline code works:
<% def xxxService = application.getAttribute("org.codehaus.groovy.grails.APPLICATION_CONTEXT").getBean("xxxService") %>
You can call functions of the service just like this:
<g:select optionKey="key" from="${xxxService.getWhateverList()}" name="tarif" value="${accountInstance?.tarif}" ></g:select>
Well I have found a workaround with the following code :
def helpersService = grailsApplication.classLoader.loadClass('HelpersService').newInstance()
However it is better to use Service via dependency injection, so I will try out Siegfried advice.
You can do this easily without creating a tag lib by using the set tag:
<g:set var="versionService" bean="versionService"/>
...
<p>version ${versionService.clientVersion}</p>
I found this solution here: http://mrhaki.blogspot.com/2013/08/grails-goodness-use-services-in-gsp.html

View Models (ViewData), UserControls/Partials and Global variables - best practice?

I'm trying to figure out a good way to have 'global' members (such as CurrentUser, Theme etc.) in all of my partials as well as in my views.
I don't want to have a logic class that can return this data (like BL.CurrentUser) I do think it needs to be a part of the Model in my views So I tried inheriting from BaseViewData with these members. In my controllers, in this way or another (a filter or base method in my BaseController), I create an instance of the inheriting class and pass it as a view data. Everything's perfect till this point, cause then I have my view data available on the main View with the base members. But what about partials?
If I have a simple partial that needs to display a blog post then it looks like this:
<%# Control Language="C#" AutoEventWireup="true" Inherits="ViewUserControl<Post>" %>
and simple code to render this partial in my view (that its model.Posts is IEnumerable<Post>):
<%foreach (Post p in this.Model.Posts) {%>
<%Html.RenderPartial("Post",p); %>
<%}%>
Since the partial's Model isn't BaseViewData, I don't have access to those properties. Hence, I tried to make a class named PostViewData which inherits from BaseViewData, but then my containing views will have a code to actually create the PostViewData in them in order to pass it to the partial:
<%Html.RenderPartial("Post",new PostViewData { Post=p,CurrentUser=Model.CurrentUser,... }); %>
Or I could use a copy constructor
<%Html.RenderPartial("Post",new PostViewData(Model) { Post=p }); %>
I just wonder if there's any other way to implement this before I move on.
Any suggestions?
Thanks!
Have you considered keeping these things in the session and writing a strongly-typed wrapper around the session that will give you access to this information? Then in any view you can simply create a new wrapper class with the ViewPage's (or ViewUserControl's) Session property and use it.

Resources