I'm working on a ruby-on-rails app that would write XML files for each section on a page. So instead of querying the database every time the user makes a request it would simply call the XML file that corresponds to that page and the javascript will parse the file. On the rails side there will be a content management system. When user is ready to commit all their content changes they will hit the publish file at which point the data which possibly was already saved in the database will now be written to an xml file.
The challenge is that I want all the xml files to live inside a folder in the main project directory called xml_display.
How do I configure the routes.rb to take a request like... myhost.com/display_xml/pagename.xml
and return the static page in rails_project_root/display_xml/pagename.xml
I've looked into High Voltage and it doesn't seem to be the solution I'm looking for.
I hope this sounds interesting to you.
You can just make a controller that redirects to your static files something like the following:
routes.rb
match '/display_xml/:id', :action => 'display'
display_xml_controller.rb
class DisplayXMLController
def display
redirect_to "http://#{host_domain}/static_xml_dir_in_public/#{params[:id]}.xml
end
end
You need to set host_domain to wherever you are running from. Most set up in a config.yml
Related
Some clarifications first.
I'm trying everything on local development environment.
In my UsersController I have a summary_csv method that builds a csv file and stores it in the /tmp/your-csv-file.csv location .
Once the system checks that the file is ready for download, I have a summary_csv.js.erb file that runs some javascript to help the user download the file, specifically, in summary_csv.js.erb, I try to do window.location="/users/download_csv"; and there is a download_csv method in the Users controller.
So I want the download to happen, but not sure about 2 things:
How should I configure routes.rb for this download_csv method
so that the download happens without throwing some kind of 'missing
views' error? (at this point I don't care whether user has to
directed to another view or can stay on the same page).
What should go into the body of download_csv method so that
window.location="/users/download_csv"; will initiate the download,
for the file located at /tmp/your-csv-file.csv?
1) Put a get method inside users resource and collections like this
resources :users do
collection do
get 'download_csv'
end
end
2) You just need to send_file, passing your file path to it, since it's ready.
Result
def download_csv
send_file(
"/tmp/your-csv-file.csv",
filename: "your_custom_file_name.csv",
type: "text/csv"
)
end
I ended up finding out the solution. Thanks to all who offered help
So window.location was the best method to use after all.
1) Set it to controller/method .
2) send_file appropriately in the body of the above method .
3) Set the correct routes in the right order.
Step 3 was critical to getting it work.
The route for controller/method must be configured exactly to not make Rails confused as to where it should route your action.
resources :users do
collection do
get 'download_csv' => 'specify which controller#which_method_name'
end
end
Im building a application where I give my clients a .js file so they can include into <head></head> and that .js file is providing some functions to my clients website.
Basically the .js file is the path to show.js.erb view. I am looking for protecting my code and looking for a way so clients/users can't just load the http://localhost:3000/js_files/2.js path on their browser and see the code.
Every client has different ID (.js path) and different website and I can detect that from my db. Is there a way so I see if the file/path is loading from my clients website and if Yes load/show the js code, otherwise not showing anything.
In other words, a way to check if file is loaded on for ex: mydomain.com or if they just copy the path into their browser.
I have read about obfuscate, but its not useful in my case.
You can use request.base_url and getting users domain name from database.
request.base_url helper:
Basically request.base_url, takes only the domain name and removed all other parts.
ex: http://domain.com/q/45/rails => domain.com
Here is my code:
<% if request.base_url == #domain.website %>
// JS CODE
<% end %>
If I understood it correctly, you want to check if your clients copied the js file on their assets or if they are using your domain on the script SRC attribute.
You think something like this may work?
Add a XHR get/post to your domain on your JS
Your domain receives the request and process the referer of the XHR (you can check on your controller on rails through request.env["HTTP_REFERER"])
I currently am working on a Django project that allows a user to upload a file (i.e. a .dat, .json, or .tar.gz), which then gets converted into the appropriate database objects with their various relations. The file can be uploaded either by using the interface on the web browser or via curl to the appropriate REST API endpoint. The site is currently a single-page sort of site that utilizes Bootstrap.js. The URL in the browser does not change whether the user is on the home page (which displays the most recent uploads) or clicks on one of the "blackboxes" uploaded ("blackbox" being the primary database object formed from the uploaded file). Clicking on a blackbox takes the user to a page of the list of "datapoints" that are inside the blackbox.
What I now need is for each blackbox page to have its own URL that can be returned in a response when a user or script uses curl to upload a blackbox. This is the pattern I was thinking of using in the URLconf:
r'^bb/(?P<bb_id>[0-9]+)/$'
where bb is short for "blackbox". How can I systematically make each blackbox page have its own URL following this pattern, when right now each blackbox page and the home page all have the same root URL (in development, localhost:8000)?
I have made some attempts (most likely very misguided) at something like this. One thing I tried was making a separate template for a blackbox page, using the extends template tag. The frontend Javascript has a function display_points that takes in a blackbox id and renders the list of datapoints, so I tried various hacky ways to call that function (which was in a file home.html) from within the blackbox page template, but nothing was successful. One thing that I hoped would work was using jQuery $.getScript for something like this:
$.getScript('blackboxes.js', function() { //blackboxes.js is the Javascript from home.html that I copied and pasted--hacky, I know
display_points({{ bb_id }});
})
but I keep getting 404 errors from trying to use $.getScript like this despite trying different paths for the Javascript file.
Also, just in case this is an important detail for this question, the front end utilizes Clusterize.js to help load the datapoints, since the blackboxes usually have at least several thousand datapoints.
One of the key things to making something like this work was the use of the right template tags in our home.html which we renamed to base.html to be more descriptive of what the template is for. urls.py was also modified so that two different URL patterns would map to the same base view in views.py; the two patterns were a "blank" pattern (i.e. r'^$') for the default home page and a pattern to view a particular blackbox (r'^blackbox/(?P<bb_id>[0-9]+)/$'). Different views would be rendered based on whether a bb_id (blackbox id) was in the URL pattern. If none, the default home view of the recent uploads would be rendered; otherwise, the datapoints of that particular bb_id would be rendered instead. In the base.html template, the if template tag was used to see if a bb_id existed; if so, the JavaScript function display_bb would be called, which takes in the bb_id to know which datapoints to display. Otherwise, the function display_10_recent_blackboxes would be called instead.
Another issue was sending a response that contained info that could be used to find and view the blackbox that was just uploaded. Originally, the main database insertion function insertBlackboxIntoDatabase would create the Blackbox model instance first and then fill it with datapoints created from the file uploaded. However, since the response is sent before that function is called, it was necessary to refactor the upload and insertion code such that the blackbox instance would be created first so that its ID could be part of the response. The ID would then be passed to the different upload functions (based on the filetype) that each end up calling insertBlackboxIntoDatabase, which now locates the Blackbox instance based on the ID passed to it and then proceeds to create and insert the datapoints.
I have a js file called create.js.erb that is in my view folder. It's supposed to be called when I try to create a record, but it isn't being called. I can't figure out why, and to be totally honest, don't even know how my app calls a js file in the view folder, so I'm not sure what code to paste here to help debug the problem.
Can anyone explain to me how js in a view folder is executed, and when I would want to put a js file in my view folder instead of in the asset pipeline?
*.js.erb files are rendered when you are using AJAX/JS with your controller actions. By default, when you call the create method, Rails will respond using HTML. This will load a new page. Sometimes you want to use AJAX instead, and that's why you create js.erb files in the view folders.
For this to work, the form and/or link_to objects you are using must be AJAX enabled (they should have a :remote => true attribute on them) If they are not specified as remote forms, they will execute the HTML instead of the JS and the create.js.erb file will never be called.
Your controller method also needs to know how to respond to js requests. You need something like:
respond_to do |format|
format.js
end
That code tells Rails to look for a file called "method".js.erb in your view folder, so in this case, create.js.erb.
These files are completely different from regular JS files you put in the asset pipeline -- these are view templates to be rendered as the result of a controller action.
You might find some Rails/AJAX tutorials helpful...here's a pretty good one that walks you through this whole process:
http://net.tutsplus.com/tutorials/javascript-ajax/using-unobtrusive-javascript-and-ajax-with-rails-3
Hope that helps, if you need more assistance please post the code for your controller and any of the view files...
I am providing a snippet for a client to paste into their static html that refers to my application.js file.
As this sits on a page that I do not have control over, and I do not want to ask the client to update their snippet every time I push a release, I am wondering if there is a way to return my digest-application.js version when the normal one is requested to ensure that the browser is getting the the most recent version?
I can set a cache-busting timestamp on the script src, but not sure this is really reliable.
Any thoughts on the best way to handle this?
we are doing something similar for our "public" javascript, which is integrated into a 3rd party web-application.
the way we do this is by creating a symlink on our asset-server during the capistrano deployment that points to the non-digest name of the file. since they are just files on our webserver, the apache does the rest.
I think the must elegant way is doing some Controller to do some redirect 302 to you assets.
You can paste to your client a code link /public-assets/my_assets
In your route create the route :
match '/public-assets/:asset_name' => 'PublicAsset#index'
And create your controller PublicAssetController
class PublicAssetContoller < ApplicationController::Base
def index
redirect_to asset_path(params[:asset_name])
end
end