Get output of Rails Action as string in Helper - ruby-on-rails

I'm using Rails 4.1.8 and I want to get the HTML output, as a string, from a certain controller inside a Helper which I'll later use in a View.
Assuming app were available at this point, this would be what I want. This, however, is just a conceptual example, not working code.
# pseudo-code
# widgets_helper.rb
module WidgetsHelper
def widget_html(widget_id)
app.get("/widgets/#{widget_id.to_s}.html")
app.response.body
end
end
I found this answer which appears to be related but I wasn't sure where to go with it.
I also read about render_to_string but I'm not sure if that's taking me to a workable solution either.
Update
That previous question has a comment that also mentions this question

Related

How can I create a route and use a path to enter the first step in a mulistep form with the Wicked gem?

I have tried using the Wicked gem 3 different times over the past 8 years. Each time, I have given up for the same reason. I'm trying again, because if I understand it, I think it will be perfect for my use case.
My main problem is that I don't understand how to actually begin the wizard. With the example used in the gem, it is an after_registration event that already has an associated user object. That is not helpful, nor do I think that example would be helpful in the majority of use cases.
There is another example about building a Product in multiple steps. However, the author fails to adequately explain the routing. From https://github.com/zombocom/wicked/wiki/Building-Partial-Objects-Step-by-Step:
Since Wicked uses our :id parameter we will need to have a route that also includes :product_id for instance /products/:product_id/build/:id. This is one way to generate that route:
resources :products do
resources :build, controller: 'products/build'
end
This also means to get to the create action we don't have a product_id yet so we can either create this object in another controller and redirect to the wizard, or we can use a route with a placeholder product_id such as [POST] /products/building/build in order to hit this create action.
OK, I have no idea what the second part of the sentence means as far as placeholder product_id and that route name of /products/building/build. I spent 2 hours trying that and just moved on to a blank create form.
...we can either create this object in another controller and redirect to the wizard
That's what I'm trying to do upon successful save of the #product object.
redirect_to product_by_interchange_path(#product, :step1)
That doesn't work. raise InvalidStepError if the_step.nil? Says my step is nil. It's not.
redirect_to product_by_interchange_path(#product, step: :step1)
Same thing.
redirect_to product_by_interchange_path(:step1)
That's an exact mirror of the 8 year old example app. But of course #product isn't in a session variable like current_user is, so in this case the error is that there's no Product with an id of :step1.
Please help! I am missing something very, very basic here but I very much need to persist.
OK I have finally figured this out. Here's what I did:
First of all, I changed my controller back to a plain old ApplicationController and used the include include Wicked::Wizard. I don't know if that did anything, but the newer example was laid out like the old.
I was really screwed up by :id. I'm thinking :id is generally my object ID. I had a set_product private method in my controller, and it was failing. When I finally figured out that :id was the actual step itself, that led me to change my path in the redirect.
I changed the redirect from product_by_interchange_path(#product, :select_vehicle) to product_by_interchange_path(:select_vehicle, product_id: #product.id)
I got rid of my set_product. Just while I was trying to eliminate confusion.
I changed my finder calls in the wizard to use :product_id instead of :id.
It works now. I still don't understand how I could have stubbed out a route with a placeholder product_id, that's still a mystery. But this is fine and it works.

ACRCloud webapi in Rails

I'm a newb hobbyist developer. Can I just throw this repo of their ACRCloud's ruby example code into a controller? I'd like to use an audio fingerprinting song recognition database as a name validation for songs users are uploading using paperclip. Not sure if it's possible, just starting to research it, any hints or suggestions would be appreciated.
Obviously I'd have to replace
file_name = ARGV[0]
etc, but I'm also wondering about the require 'openssl' etc
Definitely! But there are few points to be taken care of. That's a pure ruby script, when it comes to rails there are certain rules/best practices. One of which is thin controller and fat model..
You need to create a route/action in your app which will ask the app to execute this request with required params.
Write a method in your model which contains the code and call it from controller and pass the permitted params to it.
Instead of hardcoding your credentials in the model, make them environment variables.
Would suggest using Httparty gem wgich will reduce many lines of your code and you just need to pass headers, params, etc. as hash in the arguments.
Last, but not the least...if you notice..there's a puts in the end however, rails uses mvc and so you need to have a view for the controller action you created in step1. Return and save the response.body in the class variable like #response = res.body and you can play with the body depending on the response type.
Hope it helps..
P.S. I wish I could write few lines of code/optimise it for you but i m using my mobile right now. But I think this much information should be enough to convert that script to mvc rails structure..

Create a generic template for JSON from a rails application

I'm writing a rails application with an AngularJS front-end, this is part of a tutorial series I'm writing on connecting rails and angularjs. This means my rails application communicates with the browser exclusively in JSON.
In the angularjs $http documentation it describes a potential json security vulnerability where the json request can be embedded into a script tag, plus some tricky use of jsonp, to allow something akin to a cross-site scripting attack. I've found a few other pages, one in particular I thought described this well, and dates from 2008, so this isn't a new issue.
Apparently this isn't a vulnerability in standard rails json rendering, as rails by default provides back an object containing an array. But when working with angularjs we appear to set root: false (although I have to confess I can't find where I did that, but it's definitely not giving the root node).
Anyway, the bottom line is that the angular documentation recommends prefixing any json response with )]}', so:
['one','two']
Becomes
)]}',
['one','two']
Angular then automatically strips that off again.
I'm looking for a way to do this elegantly. I've seen a lot of questions and answers on stackoverflow about this, but most of those either relate to much earlier versions of rails before JSON handling was more thoroughly embedded, or seem to require me to create a lot of boilerplate code. I'm looking for a method that I can apply to the application controller, or as a helper method, that will work everywhere.
The controller that I'm currently using looks as follows:
class ClubsController < ApplicationController
respond_to :json
# GET /clubs.json
def index
#clubs = Club.all
render json: #clubs
end
end
This doesn't call any templates - the render action skips the templating engine. I can get this working by changing the render line instead to:
respond_with json: #clubs
And creating a template file views/clubs/index.json.erb that contains
)]}',
<%= raw(#clubs.to_json) %>
But I'd then have to create a template for every action on every controller, which feels like boilerplate. I'd like instead to be able to change views/layouts/application.json.erb to have something like:
)]}',
<%= yield %>
But that doesn't work because we only get templating if we call respond_with. And if we call respond_with, we have no way to put the #clubs into the response - so we end up with:
)]}',
As the entirety of the response.
An alternative would perhaps be to override the as_json method to prepend what I want, but that seems a bit like a sledgehammer. Ideally there would be a place I could introduce a helper method, something like:
render prepend_vulnerability_protection(json: #clubs)
So, after all that, two questions:
Is this even a real problem, or does Rails already have some other protection that means I don't need to worry about this at all
Is there a way to do this centrally, or do I need to bite the bullet and create all the boilerplate templates? I can modify the scaffold generators to do it, so it's not the end of the world, but it does seem like a lot of boilerplate code
So, no responses as yet. I'm going to write down what I find from my research, and my current answer.
Firstly, I think this is a genuine vulnerability in rails. Unfortunately the rails and JSON/JSONP area has had some other recent vulnerabilities relating to the JSON parser at the Rails end. That has really drowned out any google search relating to this specific XSS issue.
There are a couple of approaches to resolving this:
Have your application only respond to put/post/delete requests. That's not really an option when integrating to Angular - well, it is, but it means overriding a bunch of standard behaviour
Insert something at the front of your returned JSON - this can be the root node (default rails behaviour in rails 3, no longer in 3.1), a closure like )]};, or a loop like while (1);. Angular expects and can deal with )]}',
I've looked at using a json template in my rails app. You can do this with one of many gems, the one I like the look of is JBuilder (railscast 320), but RABL is perhaps more powerful (railscast 322).
This does mean a template for each of the actions on each of the controllers. However, I've also just completed working out how to have rails scaffold those for me automatically, so it's not as scary as it was when I first asked the question, and I can see some other reasons that I might want more control over the json that is returned from my application.
Having said that, I couldn't immediately see a way to get JBuilder to prepend an arbitrary string - it seems to only want to prepare valid JSON (and this I think is not valid JSON). RABL looks like it can do it, but it is a bit more complex. It can definitely be done through just using ERB, but I feel kinda wrong in doing that.
The other alternative I've identified is a helper method in application_controller.rb, which I then call in each of my controller methods. This is reasonably elegant, and I can quite easily change my template to do it. So I'm going with this for now:
class ApplicationController < ActionController::Base
def render_with_protection(json_content, parameters = {})
render parameters.merge(content_type: 'application/json', text: ")]}',\n" + json_content)
end
end
class ClubsController < ApplicationController
respond_to :json
# GET /clubs.json
def index
#clubs = Club.all
render_with_protection #clubs.to_json
end
# GET /clubs/1.json
def show
#club = Club.find(params[:id])
render_with_protection #club.to_json
end
# POST /clubs.json
def create
#club = Club.new(params[:club])
if #club.save
render_with_protection #club.to_json, {status: :created, location: #club}
else
render_with_protection #club.errors.to_json, {status: :unprocessable_entity}
end
end
end
Note that you should be also including CSRF protection in your application controller - so see this as additive to the security precautions you were already taking, not a replacement.

rails the best way to saving page duration and page loading speed

Hi I'm a beginner of rails and I'm not good at English. so if there is some total nonsense please understand..
I'm trying to record loading speed and page duration in every pages.
I made a database "pages" and method "savepage" in my "Page" model.
To save in every page I put "savepage" method in application controller.
Page.rb
def self.savepage
.
.
.
end
application_controller.rb
before_filter :dosave
def dosave
Page.savepage
end
these kind of format..
My question is
1. am I doing correct? using before_filter to do save in very first of loading process?
2. to save after loading all the contents in a page what should I use?
3. to save after user leave this page what should I use?
I saw before_destroy and after_filter, but I can't find what it is... what filter means.... what action means destroy....
thank you in advance!
before_filter is the first thing which loads before giving request to controller.But your need is completely different . Fundamentally filter are used boolean checking.If certain method is true,it will run otherwise it may not. This filter are further extended and we put code into that filters.(And Even sometimes it is consider as best practice) .
Now, before_filter :dosave might be right but is it not true way of knowing page(UI) loading process. I suggest you to use javascript call or use some manually created helper methods and place it into view .erb files.
May be this will interest you
https://github.com/grosser/record_activities
Log user activities in ROR
what action means ?
Action Controller is the C in MVC. After routing has determined which controller to use for a request, your controller is responsible for making sense of the request and producing the appropriate output. Luckily, Action Controller does most of the groundwork for you and uses smart conventions to make this as straightforward as possible.
Source : http://guides.rubyonrails.org/action_controller_overview.html
I highly suggest you to read above documentation. It is very necessary for you and it covers topic which you asked here.`
And one more thing,
what is action destroy ?
This is simply an action method just like new. Since, rails follow Convention over configuration ( and its developer too) so they put code which do some delete destroy or some destruction. This make thing simple,otherwise more configuration will require which is against rails policy.

Beginner with Rails 3.1 and "static" pages

I just started deploying a Rails website. In fact, I started programming on Rails 2 days ago.
I've created a new project, added some gems, etc. Everything is working properly, and I have some basic knowledge on how all works.
The thing is that what I want to create is a simple website with some sections (let's say, News, Contact, About, Products...). All this content is kinda static.
But I came in a problem. I don't really know what to do in order to create them. What I want, for example, is something like mypage.com/products/fashionableproduct, mypage.com/about, etc, or even mypage.com/page/products.
I thought about creating a Controller, then an action for each page... afterwards, I came up with other solution: scaffolding. Creating a resource called page, that has a title, etc...
I'm really a beginner on this topic, and I would like to hear your helpful voice.
Thanks!
Check out https://github.com/thoughtbot/high_voltage for static pages for Rails.
And check out http://railscasts.com/episodes/30-pretty-page-title for setting page titles.
The paths to your files are determined by your routes. The configuration file for routes is located at config/routes.rb. You can match a URL path, and then point to a given resource. More information about routes here: http://guides.rubyonrails.org/routing.html
If you generate a controller, you can process any dynamic data and then pass this data to these "kinda static" pages. Here is an example configuration that would match the path "mypage.com/about" and display the appropriate page:
# config/routes.rb
match "/about" => "example_controller#about"
# app/controllers/example_controller.rb
class ExampleController < ApplicationController
def about
# calculations
end
end
# app/views/example/about.html.erb
<!-- This is your HTML page -->
I think the title of your post might be a bit misleading. I have the feeling you don't want static pages but some database stored content. Just like Ben Simpson tells you to do, create a normal pages controller and make it work.
In the end you might want to customize some routes to get them to be exactly the way you want as in your examples.
Since you just started the app, I strongly recommend you start over and make a new app with Rails 3.1 which is the most current version and learn how to do the basics through http://guides.rubyonrails.org/ and a few other sources such as http://railscasts.com.
You will then learn Rails the right way from the beginning. Good luck and have fun in the process.

Resources