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.
Related
Learning Rails, the point at which a controller gets instantiated is unclear to me whereas, the point at which a model gets instantiated is somewhat recognizable as for example, when a user enters data in a from and clicks the submit button is sort of a trigger that leads to a creation of an object model.
Done some research and I'm visualizing in my head that when a HTTP request is sent via the browser, the routing to a controller becomes the trigger to instantiate a certain controller object from a controller class.
Is this somewhat correct?
When the HTTP request enters your application server (puma, webrick, etc), the request passes through a stack of middleware (defined in rails gem), which converts the HTTP request into an instance of ActionDispatch::Request class which is used to determine the correct route to dispatch to appropriate controller class in your rails app based on the route definitions defined in config/routes.rb.
The generated request object is then dispatched to the corresponding controller and action method which instantiates the Controller class and invokes an action method on it's instance with an argument of params object (instance of ActionController::Parameters).
This is just a general overview of how Controllers are instantiated. The request object passes through a series of middleware classes and modules before a request object is generated.
Here's a good article if you want to read it in detail.
As we define the routes in routes.rb, than the control goes to that controller action at that time the controller get's initiated to work
It is more related to object oriented programming, The object is always instantiated when you call new on class
2.0.0-p648 :001 > Class.new
=> #<Class:0x007fee8e99d9a8>
2.0.0-p648 :002 >
Here the object is instantiated, and similarly in rails when you call any action lets say
def new
#article = Article.new
end
new object gets initiated, when you click on save, you are actually calling create action, and pass the current object.
def create
#article = Article.create(article_params)
#article.save
end
here .create method filled object with article_params and .save method saves object in database.
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
I am following a tutorial and got to this point: http://rubysource.com/building-your-first-rails-application-views-and-controllers/
rails generate controller urls new
The reason we only passed in the new action (instead of new, create,
and show) is because Rails automatically generates a dummy view for
each action included in the generator call. In this case, we only want
a dummy view for the new action, so we exclude the others.
So why we only need to create the controller for new? Can someone plase explain it in a little more details?
The command is used to create the UrlsController with only one method: new.
This command will also automatically create a view file for you in:
app/views/urls/new.html.erb
Had you supplied more arguments like:
rails generate controller urls new create show
You would have gotten:
app/views/urls/new.html.erb
app/views/urls/create.html.erb
app/views/urls/show.html.erb
Since the tutorial only needs the new view it was unnecessary to create the additional views, hence those additional arguments were not added to the generate command.
Later in the tutorial you manually add the create and show methods, but you never add views for those methods (since those methods will not be needing specific views files in this application).
So: what you did was create the controller UrlsController with one method new, and the corresponding view for that method. The rest of the methods you will code in manually later in the tutorial so there was no need to auto-generate anything else (create or show).
This will only create the new action in the controller and should skip the other ones.
EDIT:
It will generate a controller called UrlsController in app/controllers and in that controller there will only be one method called action which corresponds to a route or url called urls/new
I have a method to generate a password in models in Users.rb file. In my view i have a form where only email address filed is there and I want to to add the password to the User attribute before saving it. I have a create method where I create a new user and save it in controller. How do I call the generate password method in the controller?
Is it a class method? Call it using User.generate_password. Is it an instance method? Call it using #user.generate_password, or whatever the instance variable is named.
I made a simple helper with one function and put it in the relevant controller_helper and I noticed that the function is valid from the whole application views.
Why is that? shouldn't the helper be valid only to his controller?
The process is the following:
If you're in a view belonging to controller foo and you call a helper called my_helper:
if defined in foo's helper, it's executed from here
if not defined in foo's helper but defined in another helper, say bar, it's executed from there
if not in foo nor in any bar, it's checked in application_helper. If it doesn't exist here, an error is raised.
That would make sense, but it's not the complete story. I have a controller MainController and a controller AlsoController, and defined a helper with the same name wherefrom in each of the helper modules ie MainHelper and AlsoHelper. But if I try to make use of wherefrom in the also view, it uses the helper defined in MainHelper instead of the one in AlsoHelper.