Rails how to view a txt file? - ruby-on-rails

How is it possiable to open an view a txt file with rails?
Example I have test.txt:
Test test test test
Then I have my test.html.erb:
Here I want to view test.txt

You can either render an arbitrary file or use send_file: 3.1 or < 3.1

Another possibility is:
Here is the test.txt file: <%= File.read("test.txt") %>

Here is the test.txt file:
<%= File.read(File.join(Rails.root, 'your_folder','your_folder','test.txt'))%>

In some cases (when the file is not small and loading it is connected with a delay), I prefer to load the page content and then to use jQuery ajax request to load the file content.
For example, let's say I have a model with file path attribute. In the view layout I am doing something like this:
<pre data-source=" <%= (#file.path) %>"></pre>
Then in the corresponding js file I am loading the context like this:
$(document).ready ->
$.ajax(
url: $("pre").data("source")
context: document.body
).done (response) ->
$("pre").html response
return
return
Of course you can check the jQuery ajax documentation for more options. For example, you can render the pre tag with loading like this:
<pre data-source=" <%= (#file.path) %>"><div class="loading"></pre>
or use other jQuery animations as well.

Related

render (partial) and scope between elements

I have a checkout popup I would like to share between different pages (event, video meeting ...), so I thunk creating a shaded element /views/shared/_checkout.html.erb, and insert <%= render "shared/checkout" %> in my pages.
Uncaught ReferenceError: popup_payment is not defined
All the html and javascript is this shared page.
I just can't understand why from my pages (event, video ...) I can not call the javascript from this shared component.
the html and the javascript is present when I check the source. I was excepting that render / render partial was acting some code injection, am I wrong ?
How could I preserve the DRY - Don't repeat Yourself - in ERB ?
And have the elements / javascript communicate betweek page and included javascript ?
Here is some pseudo code example :
pageA.html.erb
<%= link_to image_tag('pinandchip.png', size: '18x18'), '#', onclick: 'popup_payment();', class: "btn flat" %>
...
view/shared/_popup.html.erb
<script>
function popup_payment() {
}
</script>
You could try adding the class payment-popup-button to your button and create a new file in app/assets/javascripts/shared called popup.js.
In that file you can do something like:
$(document).ready(function(){
$('payment-popup-button').click(function(e){
e.preventDefault();
$('#popup_payment_div').show();
});
});
This assumes that you're using jQuery, and that you've already rendered the popup code somewhere on the page, but it's hidden.
If you need to render a fresh form every time or populate the form with dynamic data you'll probably have to create controller actions that respond_to and render js.erb to get you the right markup.
It's hard to say exactly without seeing more code.
Are you ensure that your javascript function is loaded in all pages?
On this question answer how to have global javascript functions on rails projects.
i found a solution with this gem :
https://github.com/komposable/komponent
it fulfill my needs : create external components

Call a Ruby on Rails helper method from a JavaScript js.erb file

Is it possible to call a ruby helper method from within a js.erb file?
I have a helper in application_helper.rb called solve which makes a API call to a third party service, and they only have a ruby client.
The js.erb file isn't being run on the client side, it is being called from within a controller method and run server side as it is PhantomJS.
I call the JS file from the controller
Phantomjs.run('phantom.js.erb', url)
Then within the PhantomJS js.erb file I have tried
var response = '<%= solve(variable) %>'
which just sets the variable as the string <%= solve(variable) %>
I have also tried
var response = <%= solve(variable) %>
but that just seems to make the application hang and become unresponsive.
I have seen other questions similar to this. In those questions they are asking if it is possible to call it from client side JS which I know you need to use an ajax request to do so.
Is this possible?
Try this:
var content = '#{solve()}'
Need a bit more context for this question, but I'll try my best to answer:
Essentially, you wouldn't be able to access your application_helper methods outside of any .erb files. (ie. if you have application.js or any other js file in your pipeline and you are trying to <%= solve %> from there it wouldn't work - mainly because it isn't an .erb file)
There are a lot of ways and architecture to go about solving this, but here are two simple ones:
If you put the JS you want to evaluate inline on the same page as your partial/html.erb page by using <script> //JS ERB CODE GOES HERE </script> It will actually evaluate properly since it is inside of an erb file. However, this is generally looked upon as unclean...
What you probably want to do is pass the value (presumably) you want that comes from the "solve" application_helper in a 'data' attribute on the html element that it affects. By utilizing "unobtrusive javascript" in this way, you simply pass the value through markup and then in your JS you can get the variable by using jQuery code like this. Here's an example:
<%= link_to "test_link", root_path, :data => {:solve => solve } %>
Of course it doesn't have to be a link, any HTML element will do, and then in your jQuery:
$("#test_link").data("solve");
will return to you whatever output comes out of your "solve" method in the application_helper.
it can possible but there are different ways to do it. one way is define the method in helper_method in your controller and call it from your view. and another way is use the gon gem to access some controller value in your javascript. please check what is best for you please check the below links for more help
http://apidock.com/rails/ActionController/Helpers/ClassMethods/helper_method
https://github.com/gazay/gon
http://railscasts.com/episodes/324-passing-data-to-javascript

Rails asset pipeline: How to prevent caching of a specific asset

As stated in the title I want to prevent caching of a specific asset, namely a javascript file something.js.erb. The situation is like as follows:
Content of something.js.erb:
...
var something = <%= SomethingHelper.get_something.to_json %>;
...
It binds the value from SomethingHelper successfully but only once and unless the javascript file is edited by hand the value of var something is never assigned again.
This might be somehow expected but clearly doesn't meet my needs. Output of SomethingHelper.get_something changes according to call time. So I need to see up-to-date data in my compiled something.js file.
My exact need:
I don't want to disable asset pipeline caching as a whole
I only want something.js.erb to be rendered every time it is requested.
is this even possible?
Environment info:
Rails 4
Development mode
Rails' own server but will be on nginx on prod
Thanks
I can suggest 2 options:
1)Use inline js to set variable:
<%= javascript_tag do %>
window.something = '<%= j SomethingHelper.get_something.to_json %>';
<% end %>
2)Store the variable in your html and call it from your js:
#html
<body data-something="<%= j SomethingHelper.get_something.to_json %>">
</body>
#js
$("body").data("something");
You're marrying front-end business logic with data. This is inadvisable, and one of the reasons I don't use or recommend using ERB + JS for most scenarios (especially triggering behavior on response like Rails tutorials and guides are keen on doing). You are better off either…
Firing a request off to fetch the data from your JavaScript.
Provided the variable is going to be used on every page (or close to it) and is relatively brief, non-binary data, you can embed a meta tag in your layout with the relevant information.
For example:
# /app/views/layouts/application.html.erb
<%= tag :meta, name: 'something', content: #something %>
# /app/assets/javascripts/application.js
$('meta[name="something"]').attr('content');

How to avoid embedding javascript in views/show

I have a Rails app that uses javascript (Backbone) to show user specific data on each users profile page /views/users/show.html.erb. I do this by passing <%= #user.id %> as a data parameter to Backbone's fetch function, however, the only way I know how to get the <%= #user.id %> into Backbone's fetch function is by embedding the javascript in each views/users/show.html.erb page, which therefore allows Backbone to load different user specific info for each views/users/show.html.erb page. Although this works, it seems like the wrong way to do it, as I have read that I should not embed javascript like this. Furthermore, I am going to have to do it a lot, because I wish to display a lot of different kinds of data, more than you see below. So the show.html.erb page will be filled with javascript to make the app work the way I wish.
Question: how might I get #user.id into Backbone's fetch function for each user's show page without embedding javascript in the way that I've done. In the comments, someone suggest I use app/assets/javascripts/user.js, but I don't know how to get <%= #user.id %> into that file. #user.id is readily available in show.html.erb
<script type='text/javascript'>
$(document).ready(function() {
app.collections.awardCollection.fetch({ data: $.param({ user_id: <%= #user.id %> }) }).complete(function(){
app.views.awardCollection = new app.Views.awardCollection({ collection : app.collections.awardCollection});
app.views.awardCollection.render()
});
});
</script>
In order to understand how the views works, is that you can add as many extensions to a view as you want, and they will be parsed by the right library.
If you create a view like
my_view.haml.erb
It will be first parsed with ruby (erb), and then with haml, and will end in a html page.
You can create many views for js, usually you want to archive that when you do ajax, so you can end having a js view like:
my_view.js.erb
First ruby will be parsed (all the <% %> tags), that will end as plain text, and then the server will serve the .js file. But that's usually a common task for ajax.
If you have to render a html page where you want to put some js and you need some ruby code on it, what I usually do is to put the data in the html content with a hidden div.
You can put in any view (even on your layout if you want it to be globally available), something like:
<div id="user_id" style="display: none;"><%= #user.id %></div>
And then on a js (or coffeescript or whatever) you can just check the content of that div:
<script type="text/javascript">
var user_id = $("#user_id").html();
</div>
that's really useful when you want to debug or create tests for your js files, since its plain js and won't throw syntax errors.
I see the comment of Luís Ramalho and Gon is a good option, but I recommend use the following approaches:
If the from the variable is not going to change, print it with <%= %> under .js.erb files located in app/assets/javascripts (note that it will be cached until you restart your app)
If you need server variables the best way is to use Ajax
You can define functions on .js files on app/assets/javascripts and call those functions from the views
If you really don't want any Javascript code in the view, you can create the functions on a .js on app/assets/javascripts (corresponding to the view, for order), and use events and/or store the variables in hidden fields (or even use the data attribute from HTML5)

Autocomplete with local data in Rails

In my application, users pick train stations from an autocompleting text field. Since there aren't many train stations (~100), I'd prefer for the field to autocomplete based on the contents of a client-side array rather than querying the server each time the user types a character (the goal is to make the autocomplete more responsive).
My question is how to do this in Rails in a maintainable, non-hacky way. My current solution is just putting this line at the bottom of index.html.erb:
<%= javascript_tag "var stations = #{Station.all.map {|s| s.name}.to_json}" %>
but this isn't great (for one thing, I have to remember the "stations" variable name while I'm working on application.js).
You can make a dynamically generated Javascript view file similar to how I show here.
Basically if you have a controller action (such as a javascripts controller stations action). It might look like this.
# in controllers/javascripts_controller.rb
def stations
#stations = Station.all
end
you can then make a JavaScript view file like this...
// in views/javascripts/stations.js.erb
var stations = <%= #stations.map(&:name).to_json %>;
// ...
That javascript file can contain whatever javascript you want, so you can likely move some of application.js code there. You can then include this just like any other javascript file.
<%= javascript_include_tag 'stations' %>
This assumes it's under the 'javascripts' path which happens to be the case if you have a javascripts controller. Otherwise you'll have to pass the full path.
This does have the downside by making one more request to the Rails app, but you can likely add page caching to that js action to optimize that.
In your application.js, on document ready, do an ajax call to fill a local array with the values.
document.observe("dom:loaded", function() {
var stations;
new Ajax.Request(url, {
method: 'get',
onSuccess: function(transport) {
stations = transport.responseText;
}
});
});
My example might not work perfectly (as I use jQuery through jrails now), but it should give the right impression.

Resources