Ruby on Rails Edit File Template? - ruby-on-rails

I have a HTML/CSS File laid out with a bunch of areas that need adding. I have a ruby on rails application that would have a bunch of form elements that would then need to be added to this HTML/CSS file (it doesn't need to be shown or anything, just edited and then saved). I don't really understand how I can do this. I was looking at the file class, but got lost very quickly.
Any easy way to do this?

Writing to a file in Ruby is very simple:
File.open(filename, 'w') do |f|
f.write(content)
end
For an example in Rails try the following steps. Generate a new Rails app and a dummy scaffold by running:
rails new erbfun
cd erbfun
rails g scaffold Stylesheet custom_css:text
rake db:migrate
mkdir -p public/system/stylesheets
Then do something like this in your model:
class Stylesheet < ActiveRecord::Base
require 'erb'
FOLDER = File.join(Rails.public_path,'system/stylesheets')
TEMPLATE = <<-CSS
body {
font-family: Helvetica;
}
<%= custom_css %>
/* some css comment here ... */
CSS
def save_to_file
template = ERB.new(TEMPLATE)
document = template.result(binding)
filename = File.join(FOLDER,"stylesheet-#{Time.now.to_i}.css")
File.open(filename, 'w') do |f|
f.write(document)
end
end
end
and then try it out:
$ rails c
Loading development environment (Rails 3.2.2)
1.9.3p125 :001 > s = Stylesheet.new custom_css: 'foobar'
=> #<Stylesheet id: nil, custom_css: "foobar", created_at: nil, updated_at: nil>
1.9.3p125 :002 > s.save!
...
=> true
1.9.3p125 :003 > s.save_to_file
=> 94
1.9.3p125 :004 > exit
$ cat public/system/stylesheets/stylesheet-1332633386.css
body {
font-family: Helvetica;
}
foobar
/* some css comment here ... */

Related

How do I write a function in rails console?

I am trying to write a function in the rails console, and in the example, this is how the function should look in terminal.
>> def string_message(str = '')
>> return "It's an empty string!" if str.empty?
>> return "The string is nonempty."
>> end
How do they create a new line while still making the console realize it is all of the lines create a function. Would it be accurate to write it as:
>> def string_message(str = '') \n\t return "It's an empty string!" if str.empty? \n\t blah blah \n\t
?
IRB, the ruby console in which rails console relies supports this out of the box.
Just type your function declaration, press the enter key, then input the body line by line, and finally type end.
You'll see text like this:
2.4.1 :001 > def say_hi(person)
2.4.1 :002?> puts "Hi #{person}"
2.4.1 :003?> end
=> :say_hi
2.4.1 :004 > say_hi("Nina")
Hi Nina
=> nil
2.4.1 :005 >
Notice how the ? indicates that IRB is waiting for more input before evaluating the expression.

rails saving recognized link from text to database with rinku

I have a rails app with chat. In the chat for the messages I use rinku gem to recognize links which works well. On the top of this I would like to save the links as message.link without the rest of the text around it from the message.body.
So for example in the code below the user sent the message.body "hi there www.stackoverflow.com" and I would like to save only the "www.stackoverflow.com" as message.link. How can I do that?
view
<p><%= find_links(message.body) %></p>
controller
def find_links(message_body)
Rinku.auto_link(message_body, mode=:all, 'target="_blank"', skip_tags=nil).html_safe
end
it will appear in the DOM as:
<p>hey there http://stackoverflow.com/</p>
and will appear in the db as message.body:
"hey there http://stackoverflow.com/"
UPDATE:
messages controller
require "uri"
def create
.....
if message.save
link = URI.extract(message.body)
update_attribute(message.link = link)
end
You need regular expression to identify URLs from text. Try following regular expression:
/(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/
Working demo: http://rubular.com/r/bHQdFHZYFH
2.1.2 :001 > str = "hey hi hello www.google.com https://stackoverflow.com http://tech-brains.blogspot.in"
2.1.2 :002 > regexp = /(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/
2.1.2 :003 > str.scan(regexp)
=> [["www.google.com"], ["https://stackoverflow.com"], ["http://tech-brains.blogspot.in"]]
You can use Ruby code:
2.0.0-p247 :001 > require "uri"
=> true
2.0.0-p247 :002 > URI.extract("hey there http://stackoverflow.com/")
=> ["http://stackoverflow.com/"]
Hope it helps!

Rails - How to pass Sprockets::Context in manual sass compiling

I'm using the following code snippet to manually compile a sass manifest with some variable overrides appended.
template = File.read("#{Rails.root}/app/assets/schemes/#{scheme}/css/styles.css.scss")
scheme_variables.each do |key, value|
template << "$#{key}:#{value};\n"
end
engine = Sass::Engine.new(template, {
:syntax => :scss,
:cache => false,
:read_cache => false,
:style => :compressed,
:filesystem_importer => Sass::Rails::SassImporter,
:load_paths => MyApp::Application.assets.paths,
:sprockets => {
:context => ?,
:environment => MyApp::Application.assets
}
})
output = engine.render
The Sass::Engine constructor wants a sprockets context and environment in the options hash. What do I put in for the context? The first thing I tried was...
:context => MyApp::Application.assets.context_class,
...but that gives me the following error "undefined method `font_path' for #" when it hits one of my sass asset helpers.
The second thing I tried was...
:context => ActionController::Base.helpers,
...That fixed the asset helper issue, but throws the following error "undefined method `depend_on' for #" when it tries to work through my glob imports (e.g. #import "mixins/*").
I'm using Rails 4.2 and sass-rails 5.0.3.
Any advice on this would be much appreciated. Thanks!
With using Sass::Rails::ScssTemplate you can render your sass code with this snippet:
template = '...' # Your sass code
logical_path = pathname = ''
environment = Rails.application.assets
context = environment.context_class.new(environment, logical_path, pathname)
template = Sass::Rails::ScssTemplate.new(pathname) { template }
output = template.render(context, {})
If you want to render from a file then just add its path to pathname and its asset path to logical_path.
For me it works with Rails 4.2.5.1 and sass-rails 5.0.4.
I ended up solving this in a slightly different way - using Sass::Rails::ScssTemplate's render method. Basically, I write my altered css string out to a file and pass it into the Sass::Rails::ScssTemplate constructor. I then compile and remove the temp file when it's done. This doesn't feel great, but it's working well for me.
scheme_css_dir = "#{Rails.root}/app/assets/schemes/#{scheme}/css"
css = File.read("#{scheme_css_dir}/styles.css.scss")
variables_str = ''
scheme_variables.each do |key, value|
variables_str << "$#{key}:#{value};\n"
end
css.gsub!('#import "./variables";', variables_str)
file = Tempfile.new(['styles', '.css.scss'], scheme_css_dir)
file.write(css)
file.close
abs_path = file.path
relative_path = abs_path[Rails.root.to_s.size + 1..-1]
template = Sass::Rails::ScssTemplate.new(abs_path)
environment = Evrconnect::Application.assets
context = environment.context_class.new(
:environment => environment,
:name => relative_path,
:filename => abs_path,
:metadata => {}
)
output = template.render(context)
file.unlink
To answer your original question, you need to supply either the current view_context, or create one with ActionView::Base.new.
http://apidock.com/rails/AbstractController/Rendering/view_context
In Rails 5.x, Sprockets v3.7.x
NOTE: Following method requires: Rails.application.config.assets.compile == true, i.e., set config.assets.compile = true. Check Sprockets README
I manually returned compiled source for sass/js, using the following code.
# For Scss Assets
def pdf_stylesheet_link_tag(name)
if Rails.env.development?
asset = Rails.application.assets.find_asset(name + '.scss')
raw ('<style type="text/css">' + asset.source + '</style>')
else
raw ('<style type="text/css">' + pdf_asset_contents(name, '.css') + '</style>')
end
end
# For Javascript Assets
def pdf_javascript_include_tag(name, *type)
if Rails.env.development?
if debug? # Can be used to check `debug == true` in params for current route
javascript_include_tag(name)
else
asset = Rails.application.assets.find_asset(name + '.js')
raw ('<script>' + asset.source + '</script>')
end
else
javascript_tag pdf_asset_contents(name, '.js')
end
end
Above code actually helps to dynamically pass compiled version of sass/js
to Wicked_PDF, which actually helps to load styles and js on Generated PDFs, for Dev Environments.
pdf_stylesheet_link_tag can be used as a helper for templates, in development/stage (where, config.assets.precompile == false), instead of using wicked_pdf_stylesheet_link_tag(which actually requires a path to precompiled source-file).
After overnight trial and errors, I found and want to share todays's way of doing it ("today" meaning: rails 5.2.1 and sprockets 3.7.2).
Work as expected: no need of a temp file, accept #import, allow asset path helpers.
# Compile SASS and return the resulting string
# Pass the file path and name without 'sass' extension, relative to assets/stylesheets
def compile_sass(stylesheet)
# Load file content
path = Rails.root.join 'app', 'assets', 'stylesheets', "#{stylesheet}.sass"
sass = File.read path
# Configure engine
environment = Sprockets::Railtie.build_environment Rails.application
scope = environment.context_class.new environment: environment, \
filename: "/", metadata: {}
scope.sass_config.merge! cache: false, style: :compressed
# Compile
engine = Sass::Rails::SassTemplate.new {sass}
engine.render scope
end
Other sass_config options can be found here : https://github.com/sass/ruby-sass/blob/stable/doc-src/SASS_REFERENCE.md#options
The following works with rails 5.2.0, sprockets 3.7.2, sassc-rails 1.3.0 and sassc 1.12.1:
template = '...' # Your sass code
environment = Sprockets::Railtie.build_environment(Rails.application)
engine = SassC::Rails::SassTemplate.new
engine.call(environment: environment,
filename: '/',
data: template,
metadata: {})[:data]

Wice_Grid CSV export not working - Uninitialized constant CSV::Writer

I "inherited" a rails aplication running with ruby 1.8.7 in development.
I have a wice_grid table which I'm trying to export in CSV and in development all goes perfect.
When I push it to production, i get the following error:
uninitialized constant CSV::Writer
The production machine is running Ruby 1.9.1 and from what I read, I suppose the problem comes from there.
I've tried to put:
required 'csv'
In the controller or the model, but nothing happens, development works, production does not.
Here is the controller code:
def index
require 'csv'
#service_requests = initialize_grid(ServiceRequest,
:name => "solicitudes",
:order => "created_at" ,
:order_direction => 'desc',
:include => [:user, :service],
:enable_export_to_csv => true,
:csv_file_name => 'Listado de Solicitudes'
)
export_grid_if_requested('solicitudes' => 'service_requests') do
#Si se pulsa en exportar se exportan todos las celdas de la tabla seleccionada (con filtros aplicados)
end
end
Here is the part of the view, which calls a partial:
<%= render :partial => 'service_requests' %>
Here is the partial, cropped for making the question not too long:
<%= grid(#service_requests, :show_filters => :always) do |service_request|
[...]
service_request.column :column_name => 'Nombre' , :attribute_name => 'name', :model_class => User do |sr|
sr.user.name
end
service_request.column :column_name => 'Apellidos' , :attribute_name => 'lastName' , :model_class => User do |sr|
sr.user.lastName
end
[...]
end %>
I read this thread but didnt help me much: write csv in ruby 1.9 and CSV::Writer
Thank you all in advance!
Somewhere, that you haven't posted, you are referencing CSV::Writer. This works locally because you're using Ruby 1.8.7, but your production server is using Ruby 1.9.1. CSV::Writer was deprecated with Ruby 1.9.
From the the docs:
# * The old CSV's Reader and Writer classes have been dropped.
Step one is to upgrade your local Ruby to the same version as the server. This will give you the same error locally, which should go away once you find and remove that CSV::Writer.
The CSV docs give examples of how to use the current CSV class to accomplish what CSV::Writer used to do. Here's an example:
# == Writing
#
# === To a File
#
# CSV.open("path/to/file.csv", "wb") do |csv|
# csv << ["row", "of", "CSV", "data"]
# csv << ["another", "row"]
# # ...
# end
Upgrading Ruby will probably raise other errors. But Ruby 1.8.7 was retired in 2013 so these are problems you're going to want to fix now rather than later.
Good luck!

How can I load UrlHelper and the routes in the Rails?

I want to include the routes and the link_to method in a PORO. While testing this in the console I came accross this:
If I include UrlHelper without the routes helper everything seems to work fine:
ruby-1.9.3-rc1 :001 > Rails.version
=> "3.2.0.rc2"
ruby-1.9.3-rc1 :001 > include ActionView::Helpers::UrlHelper
=> Object
ruby-1.9.3-rc1 :002 > link_to "foo", Rails.application.routes.url_helpers.ponies_path
=> "foo"
If I include the routes:
ruby-1.9.3-rc1 :001 > include ActionView::Helpers::UrlHelper
ruby-1.9.3-rc1 :003 > include Rails.application.routes.url_helpers
=> Object
ruby-1.9.3-rc1 :004 > link_to "foo", ponies_path
I get the following error:
NameError: undefined local variable or method `controller' for #<ApplicationController:0x007fa1497ecc40>
What am I doing wrong here?
As suggested you should use the app object for the routes part and you should be using the helper object for the link_to.
No need to include any of the helpers through Ruby when using the console:
helper.link_to "foo", app.ponies_path
Use the app object.
> link_to "foo", app.ponies_path

Resources