How to save a rendered view to file with Rails 4.2 - ruby-on-rails

My website has an RSS feed with a route http://example.com/rss
I have now to provide a feed for Outbrain, and they need a feed with about 5000 contents. I can provide the feed "live" but I choose to add a task scheduled with whenever to save my feed offline in the public folder. Every night I will update the feed.
I add a class method to my content class...
def self.render_outbrain
data = render_to_string( :controller=>:NewsFeedController, :action => :outbrain )
File.open('outbrain.xml','w'){|f| f << data }
end
But it doesn't work in Rails 4.2:
NoMethodError: undefined method `render_to_string' for main:Object
I want to save the output of http://example.com/rss to a static file http://example.com/feed.rss
Edit
Here is my task:
task :generate_feed_rake => :environment do
session = ActionDispatch::Integration::Session.new(Rails.application)
session.get "/generate_feed"
end
Here is my controller
def generate_feed
# the news items
#items = Content.published.limit(1000)
# this will be our Feed's update timestamp
#updated = #items.first.updated_at unless #items.empty?
respond_to do |format|
format.atom { render :layout => false }
format.rss { redirect_to feed_path(:format => :atom), :status => :moved_permanently }
end
end

render_to_string is defined in ActionController::Base. Unless your class inherits from that class, it makes sense that your object doesn't know how to render_to_string.
It's not clear what exactly you're trying to accomplish, but the way render_to_string works is, in a controller, instead of rendering an HTML view for the browser, you simply send back the HTML as a string

Related

Cant get SQL object from another class

I have an extension for RefineryCMS. In that extension I need to get data from object Block in the PagesController.
My code:
def show
if should_skip_to_first_child?
redirect_to refinery.url_for(first_live_child.url) and return
elsif page.link_url.present?
redirect_to page.link_url and return
elsif should_redirect_to_friendly_url?
redirect_to refinery.url_for(page.url), :status => 301 and return
end
#block = Refinery::Blocks::BlocksController::Block.find_by(:name => 'Footer')
render_with_templates?
end
In development the first launch is successful, but after refreshing or redirecting to another site's page:
uninitialized constant Refinery::Blocks::BlocksController::Block
can you paste whole code of your controller and model.
I think problem in this line.
#block = Refinery::Blocks::BlocksController::Block.find_by(:name => 'Footer')
You are trying to access from controller.
Use Model name like
Module::Model.find_by(:name => "Footer")
Answer: https://github.com/refinery/refinerycms/issues/3051

ActiveAdmin Custom Pages

I'm trying to pass a variable from my controller to a custom activeadmin page but I can't seem to figure it out.
I basically have a form that uploads a file and it parses it. If it reaches an error, it throws one and redirects to the custom page.
class ToolController < ApiController
def import
begin
Schedule.Parse(data)
rescue MissingDependencyError => e
#dependencies = "test"
redirect_to admin_import_path({}.merge(flash_error: "Missing Dependencies", dependency_error: true, :locals => { :m => e.object }))
end
end
class MissingDependencyError < StandardError
attr_reader :object
def initialize(object)
#object = object
end
end
ActiveAdmin.register_page "Import" do |lab|
menu false
content do
#dependencies
end
end
#dependencies comes back as nil -> why?
I can pass it through the params hash but that's not the right way.
Instance variables are not available after a redirect_to ... the redirect_to creates a new controller instance and all the instance variables of the previous controller object are gone.
Instead of the params hash, you can use the sessions hash
session[:dependencies] = "test"
and
content do
session[:dependencies]
end

Rails: how do I use a template from somewhere other than the file system?

I have an application that needs to support a small set of trusted users uploading new templates. I'll store them in the database or in S3. My question is: how do I tell the controller to render a given template? Of course, I could do it with a manual ERB call:
class MyController < ApplicationController
def foo
template_source = find_template(params[:name])
template = Erubis::Eruby.new(template_source)
render :text => template.result({ :some => #data })
end
end
But then I lose things like helpers and the automatic copying of instance variables.
You could do it using render :inline
render :inline => find_template(params[:name])

Rails 3 Custom Method Location

I am currently trying to add some parsing methods to a controller method in a Rails 3 application.
I have a controller action as follows:
def control
#device = Device.find(params[:id])
<do things>
parse_return(#returned_data)
end
and I added a custom method to the controller as below (this method would not have any routes and would only be accessible to controller actions):
def parse_return
<parse data>
end
but this does not appear to allow the parse_return method to be used. Is there somewhere else in the Rails app that I can put re-usable methods?
Thanks!
At a first glance it seems that you fail to render a response. Is it true that control action doesn't have an associated view?
In this case you have to manually call render in your action. For example, to render JSON response you can do this:
def control
# ...
render :json => parse_return(#returned_data),
:content_type => 'application/json',
:layout => false
end
You should include what the errors are.
What happens if you try this?
def parse_return(returned_data)
<parse data>
end
Perhaps the method is not expecting an parameter to be passed along with it.

Need help returning

I am building a small application in RoR that has a form asking for a URL. Once the URL has been filled in and submit button is pressed I have downloaded a web-scraping plugin scrAPI(which is working fine) which gets the of URL and creates a record in db with title.
My issue right now is that I am able to make the whole thing work if the URL is valid and scrAPI is able to process it. If a URL entered does not work it gives this "Scraper::Reader::HTTPInvalidURLError" which is expected, but my knowledge of working in Model is preventing me from handing that error in a correct manner.
Controller:
#controller
class ArticleController < ApplicationController
def savearticle
#newarticle = params[:newarticle]
#link = #newarticle["link"]
#id = #newarticle["id"]
Article.getlink(#link)
success = Article.find(:last).update_attributes( params[:newarticle] )
if success
render :partial => 'home/articlesuccess'
else
render :partial => 'home/articlebad'
end
end
end
# model
require 'scrapi'
class Article < ActiveRecord::Base
attr_accessor :getlink
def self.getlink(link)
scraper = Scraper.define do
process "title", :title => :text
result :title
end
uri = URI.parse(link)
Article.create(:title => scraper.scrape(uri))
end
end
How to:
1) Handle the Scraper::Reader::HTTPInvalidURLError properly, so text could be returned to view with proper error.
2) I would also like to know how I can return 'uri' from model and use it in the controller or view.
3) Also, I would like to return the ID of the Article created in Model so I can use that in the controller instead of doing find(:last) which seems like bad practice.
Something like...
class ApplicationController < ActionController::Base
rescue_from 'Scraper::Reader::HTTPInvalidURLError', :with => :invalid_scrape_url
private
def invalid_scrape_url
flash[:error] = 'The URL for scraping is invalid.'
render :template => 'pages/invalid_scrape_url'
end
end
rescue_from is what you need.
That's 1)
for 2) You could just use #uri but personally I'd create a new model called Scrape and then you can retrieve each Scrape that is attempted.
for 3) I'm not quite sure of the question but
#article = Article.create(:title => scraper.scrape(uri))
then
#article.id
Hope that helps!
(1) In Ruby, you can handle any exception as follows:
begin
# Code that may throw an exception
rescue Scraper::Reader::HTTPInvalidURLError
# Code to execute if Scraper::Reader::HTTPInvalidURLError is raised
rescue
# Code to execute if any other exception is raised
end
So you could check for this in your controller as follows:
begin
Article.getlink(#link)
# all your other code
rescue Scraper::Reader::HTTPInvalidURLError
render :text => "Invalid URI, says scrAPI"
rescue
render :text => "Something else horrible happened!"
end
You'll need to require 'scrapi' in your controller to have access Scraper::Reader::HTTPInvalidURLError constant.
I would probably make the creation of the new Article and the call to scrAPI's method separate:
title = scraper.scrape(uri)
Article.create(:title => title)
(2) and (3) In Ruby, the last statement of a method is always the return value of that method. So, in your self.getlink method, the return value is the newly created Article object. You could get the ID like this in your controller:
article = Article.getlink(#link)
article_id = article.id
You may need to refactor the code a bit to get the results you want (and make the code sample on the whole cleaner).

Resources