How can I use image_path inside Rails 3 Controller - ruby-on-rails

An identical question has been asked before
AssetTagHelper::image_path outside views
but the solution does not work for Rails 3.
I have a requirement where I am returning some data using JSON format and part of the data needs to return the full path of the image. I am building the response in the controller and calling render :json. I am also specifying an asset_host in the environment.rb so I need a way to include that in the returned data from inside a Rails controller.

You can use view_context in your controller when doing 'view' tasks like generating links. The good thing about it is you don't have to include the view helpers in your controller.
e.g. in your controller you can create a variable which will be a html link with link_to or url_for if you just want the link, 'only_path' option set to false should give you absolute url.
link = view_context.url_for(:action => 'login', :controller => 'members', :only_path => false)
Hope this helps.

Related

calling a ruby function from rails - it takes to a view which I don't want

I want to make a ruby function called within rails. I followed this question, but I get redirected to
http://localhost:3000/my_func?arg=arg
which I don't want. I only want to execute the function when the button is clicked, but remain on the same page!
EDIT:
I modified the code, or better yet, made a scratch site just to solve this. I only did:
rails new eraseme
cd eraseme
rails g controller public home
app/controllers/public/home.html.erb
class PublicController < ApplicationController
def home
end
def my_func
end
end
app/views/public/home.html.erb
<%= button_to "Button", {:action => "my_func", :arg => "arg"} %>
What I want to do, is execute my_func when I click the button. But when I click, I get
No route matches {:action=>"my_func", :arg=>"arg", :controller=>"public"}
So, from what I can tell. I think you want to make a button that will send an AJAX/HTTP request to the Controller in order to call a function, that won't return a HTML file at completion.
In order to accomplish this, you must do the following.
1.) Set the HTTP routing for this call, this is within the config/routes.rb file.
match '/public/my_func' => 'public#my_func'
This allows your application to direct any HTTP requests with the following URL to call your method within the controller. Your button_to method will send this call with that URL due to the :action => "my_func" param.
2.) Also include the :remote => true, :form => { "data-type" => "json" } as more parameters to the button_to method.
This will transform the button from a traditonal HTTP request to an HTTP Request via AJAX request.
Let me know how this works, I think there are alternatives to using AJAX in this case, if its a very simple method then you can perhaps include it within the view as erb.

Rails form parameters: params[:controller][:variable] or params[:variable]?

In a Rails controller receiving a form POST, is it better to refer to parameters as params[:controller][:variable] or simply params[:variable]?
Rails' form helpers appears to name some fields as controller[variable] in the view, but the the controller somehow knows how to find the value when the controller uses params[:variable]. In other cases, it doesn't seem to know, particularly when I use a different controller name (e.g. form_for(#model, :as => :othercontroller, :url => :othercontroller_path(#model)).
The Rails documentation indicates that params[:variable] is sufficient, but this doesn't seem to be the case?

How to do user content from CMS in Rails

I'm trying to build a CMS in Rails from scratch, and for showing the user generated pages I'm having trouble deciding exactly how to do it.
The way I have it right now, I have a controller named 'content' with a single action called 'show'. In routes.rb I have a rule that passes any name after the name of the website to the content controller, show action with parameter name.
For example, www.mysite.com/about_us would route to
:controller => 'content', :action => 'show', :page => 'about_us'
Inside the content controller, I do a find on the Pages model to locate the named page:
#markup = Page.find_by_name(params[:page])
And then in the show.html.erb view I use the raw helper to display the content:
<%= raw #markup.text %>
Does this method violate anything about the way I should do be doing things in Rails? Or is this an OK solution?
I ended up using the sanitize helper, by default it removes <script> tags which is essentially what you need to prevent XSS, as far as I understand. For those who have found this via a search, the only code that changes from what I described above is that in the view you change to:
<%= sanitize #markup.text %>

Full URL with url_for in Rails

How can I get a full url in rails?
url_for #book is returning only a path like /book/1 and not www.domain.com/book/1
Thanks (and sorry if the answer is obvious. Im learning rails!)
According to the docs, this shouldn't happen. The option you're looking for is :only_path and it's false by default. What happens if you set it to false explicitly?
url_for(#book, :only_path => false)
While you can use url_for you should prefer Ryan's method when you can - book_url(#book) for a full url or book_path(#book) for the path.
If it's a RESTful resource you'll be able to use this:
book_url(#book)
In Rails 4, url_for only takes one argument, so you need to pass an array with an explicit hash inside for the only_path option.
Good:
url_for([#post, #comment, {only_path: true}])
Bad:
url_for(#post, #comment, {only_path: true})
url_for([#post, #comment], {only_path: true})
From the source, url_for with an Array input just calls:
polymorphic_url([#post, #comment], {only_path: true})
as shown in #moose's answer.
As noted by #lime, only_path is generally not needed for polymorphic_url since you distinguish that with the _url _path suffixes.
It seems that this would work:
url_for(#book)
But it does not. The url_for method accepts only one argument, which can be either a string, an instance of a model, or a hash of options. This is rather unfortunate, as it would seem like you may need to link to #book and add options like :only_path or :host as well.
One way around it is to use polymorphic_url, which would render the correct absolute url even though your model is (likely) not actually polymorphic:
polymorphic_url(#book, :host => "domain.com")
Perhaps the best route would be to use a named route, which is set up automatically for you when declaring resources in your routes or using the :as option:
# in routes.rb:
resources :books
# or
get "books/:id" => "books#show", as: :book
# in your view:
book_path(#book, :host => "domain.com")
Use the :host option. For example, you can use:
url_for(#book, :host => "domain.com")
Note: with Rails 3 and above, use polymorphic_url instead of url_for.
In Rails 5, if you want the full url for the current controller/action (== current page), just use:
url_for(only_path: false)
Long answer:
In Rails 5, url_for in a view is ActionView::RoutingUrlFor#url_for. If you look at it's source code (https://api.rubyonrails.org/classes/ActionView/RoutingUrlFor.html#method-i-url_for), you'll see if you pass a Hash (keyword parameters are cast into a Hash by Ruby), it actually calls super, thus invoking the method of same name in it's ancestor.
ActionView::RoutingUrlFor.ancestors reveals that it's first ancestor is ActionDispatch::Routing::UrlFor.
Checking it's source code (https://api.rubyonrails.org/classes/ActionDispatch/Routing/UrlFor.html#method-i-url_for), you'll read this:
Missing routes keys may be filled in from the current request's
parameters (e.g. :controller, :action, :id and any other parameters
that are placed in the path).
This is very nice, since it will build automatically a URL for you for the current page (or path, if you just invoke url_for without the only_path: false). It will also intelligently ignore the query string params; if you need to merge those, you can use url_for(request.params.merge({arbitrary_argument:'value'})).

rails view without a controller

Can rails handle creating a view without a controller? For example, let say I have a page that just links to other pages, would I need to create a dummy controller for that, or could I just do something in my routes file?
I like August's answer but I have a slightly different method.
Let's say you want to add
/any/path/somefile.html.erb
but not add a controller...
You can just add folder to views called "application", create your file in that directory..
Then in your routes file just add
match '/any/path/somefile' => 'application#somefile'
Your erb still evaluates, you get your layout, and you can create any path you want...
(all this does is remove the need for the pages controller)
Hope it helps...
No. All requests has to go through a controller.
I like to have a PagesController, with map.page ":action", :controller => "pages". That way, I can create app/views/pages/foo.erb and have it available on /foo without any extra code.
Another option would be adding a static html file in your /public directory if you truly don't need it as part of your application.
If you are a brave soul. You can try edge rails 3. Katz demonstrated this possibility on his blog. Here is the link:
http://yehudakatz.com/2009/07/19/rails-3-the-great-decoupling/
No. All requests have to go through a controller.
If you have a page like index.html.erb and contact.html.erb in your view folder. You need to create a dummy controller called contact. Then you can link to the contact.html.erb from the index.html.erb. And give the link as <%= link_to 'contact', :controller => "ads", :action => "contact" %> here "ads"->controller name.

Resources