Where should my rspec helpers go? - ruby-on-rails-3

I would like to write a helper that will only be used in my spec files and I do not know where this code should go.
I am not trying to test an app helper and I do not feel like creating an app helper that will only be used for testing.
What is the good practice?
Thanks,

Typically I put these in spec/support/spec_helpers. I then include those modules in the appropriate examples.
If you have some that are useful to all specs of a certain type (e.g. all request specs) then you can do
config.include SomeHelper, :type => :request
which will include that module into all your request example groups.

Related

Elixir: Access test helpers from dependency

In the java-world, artifacts for a specific library often come in two flavors, one with and one without test helpers. Is there an equivalent in the Elixir-world?
Specifically, I would like to be able to expose mocks or data generators in an application A. Application B now depends on A and gains the ability to use the exposed helpers from A in its own tests. Now, I do not want those helpers to appear anywhere in production, so they should only be included when specifically asked for (e.g. by MIX_ENV=test).
EDIT: Essentially, the question comes down to: "How to make tests from A available for the tests of B?"
Some time ago, I found a working solution: I extend elixirc_paths specifically for the :test environment and put shared helpers into another directory within the application (e.g. test/support). In mix.exs:
def project do
[
# ...
elixirc_paths: elixirc_paths(Mix.env),
]
end
defp elixirc_paths(:test), do: ["lib", "test/support"]
defp elixirc_paths(_), do: ["lib"]
Then, depending applications can use the modules in test/support when they compile the application in the test environment.

Rails 3: ActionMailer Default Layout with Inline Attachments

I have a number of mailers in my Rails 3.2 application, and I would like all of them to use the same email layout. That layout includes a header and footer, which includes images to be used inline. I'd like to follow the DRY principle of Rails, but I'm not entirely sure what the best practices are for this.
As this answer points out, I can use AbstractController::Callbacks to create a before_filter to add inline attachments. But how do I do this as well as set the layout in one module that I can then include in the mailers?
Ideas I have at the moment are to create a new mailer class called DefaultMailer, then have all mailers that I want to use the layout inherit from that class. Or to create a concern that would handle these tasks. Before attempting to hack something together using one of those techniques, I thought I would ask here to see if anyone had done this successfully before to help guide me.
AFAIK there are some issues when inheriting from other mailers (ie. not inheriting the settings).
Common solution is to create a mailer base module. This is a snippet from existing project:
module MailerBase
extend ActiveSupport::Concern
included do
helper :application
layout 'mailer'
default from: "#{AppConfig.application_name} <#{AppConfig.mailer_sender}>"
end
end
You can combine this with your callbacks, although including remote images is more common and arguably better solution.

remove new.haml/ new.erb from ruby on rails?

The default ruby on rails scaffolds generate a new.haml or new.erb these include only 1 line: = render 'form'
Thus, basically the file is obsolete, is there any preferred way to remove the new partial and make it use the _form partial instead straight away or would this go against rails conventions?
no, there is no preferred way. it goes against rails conventions.
TL;DR don't do it.
if you don't need any customizations on your templates and are just creating basic CRUD stuff, have a look at admin tools like RailsAdmin ActiveAdmin Typus etc.

Safe templates (Ruby on Rails)

Is there any plugin allowing user to create there own templates? So I use smth like
Templates.find(5).render(:val1 => val1, :val2 => val2)
There is a good plugin named liquid however it doesn't seem to be safe (user can drop database and so on).
Thank you.
Liquid is a very popular templeting system and is considered safe. In fact it was one of the design goals. From the documentation of liquid:
Liquid is a template engine which was written with very specific requirements:
It has to have beautiful and simple markup. Template engines which don't produce good looking markup are no fun to use.
It needs to be non evaling and secure. Liquid templates are made so that users can edit them. You don't want to run code on your server which your users wrote.
It has to be stateless. Compile and render steps have to be seperate so that the expensive parsing and compiling can be done once and later on you can just render it passing in a hash with local variables and objects.
The locomotive CMS use a gem called liquid that claims to do that. Check it here http://rubygems.org/gems/liquid.

Add custom methods to Rails 3.1 asset pipeline?

How can I add my custom methods to my assets such as css files like Rails did with 'asset_path' helper?
With Rail's own helper, I can write this:
# some.css.erb:
<%= asset_path 'a_image.png' %>
# How can I write this:
<%= my_custom_method 'a_image.png' %>
I've tried many ways but couldn't found a decent way to this. Do you know one?
Thanks
The best way I found was to create a custom helper module in app/helpers:
module AssetsHelper
def my_custom_helper_method
# do something
end
end
And then to require it like this in application.rb, after your applications configuration (very bottom):
module Sprockets::Helpers::RailsHelper
require Rails.root.join('app', 'helpers', 'assets_helper.rb')
include AssetsHelper
end
And you might follow this issue to find a better way: https://github.com/rails/rails/issues/3282
Normal helper methods are not available in asset views. To add you own methods you'll need to extend the Sprockets helper module. Have a look at the code of the built-in helpers to see how you might do this.
In a nutshell you can add a file in lib with the same structure as this and add you own methods. Don't forget to include the new library in you application initializer.