Best ruby-on-rails questions in July 2011

No route matches "/users/sign_out" devise rails 3

16 votes

I've installed devise on my app and applied the following in my application.html.erb file:

<div id="user_nav">
    <% if user_signed_in? %>
        Signed in as <%= current_user.email %>. This cannot be cheese?
        <%= link_to 'Sign out', destroy_user_session_path %>
    <% else %>
        <%= link_to 'Register', new_user_registration_path %> or <%= link_to 'Sign in', new_user_session_path %>
    <% end %>
</div>

I ran rake routes and confirmed that all the routes are valid.

Also, in my routes.rb file I have devise_for :users and root :to => "home#index" so this is driving me insane.

I get the following routing error when clicking the "Sign out" link:

No route matches "/users/sign_out"

I can't figure out what's causing the routing error! Please help!

Thank you for reading.

I think the route for signing out is a DELETE method. This means that your sign out link needs to look like this <%= link_to "Sign out", destroy_user_session_path, :method => :delete %>. Yours doesn't include the :method => :delete part. Also, please note that for this to work you must also include <%= javascript_include_tag :defaults %> in your layout file application.html.erb) for this to work.

rmagick and OS X Lion

14 votes

Just upgraded (i.e. not a new install) to Lion from Leopard and my previously well-working rmagick now doesn't work anymore and gives me this error:


Your Rack app raised an exception when Pow tried to run it.

LoadError: dlopen(/Users/rassom/.rvm/gems/ruby-1.8.7-p334/gems/rmagick-2.13.1/lib/RMagick2.bundle, 9): Library not loaded:
/System/Library/Frameworks/OpenCL.framework/Versions/A/Libraries/libclparser.dylib
Referenced from: /Users/rassom/.rvm/gems/ruby-1.8.7-p334/gems/rmagick-2.13.1/lib/RMagick2.bundle
Reason: image not found - /Users/rassom/.rvm/gems/ruby-1.8.7-p334/gems/rmagick-2.13.1/lib/RMagick2.bundle
~/.rvm/gems/ruby-1.8.7-p334/gems/rmagick-2.13.1/lib/RMagick2.bundle
~/.rvm/gems/ruby-1.8.7-p334/gems/rmagick-2.13.1/lib/rmagick.rb:11
~/.rvm/gems/ruby-1.8.7-p334/gems/bundler-1.0.15/lib/bundler/runtime.rb:68:in `require'
~/.rvm/gems/ruby-1.8.7-p334/gems/bundler-1.0.15/lib/bundler/runtime.rb:68:in `require'
~/.rvm/gems/ruby-1.8.7-p334/gems/bundler-1.0.15/lib/bundler/runtime.rb:66:in `each'

Tried uninstalling rmagick and re-installing, but that didn't help.

Does anybody have a solution?

Thanks :-)

I had the same problem and resolved it by uninstalling ImageMagick, removing the rmagick gem and running bundle install again.

Make sure the rmagick gem is completely gone from your ~/.rvm/gems/ruby-1.8.7-p334/gems/ folder before re-installing and running bundle install and it should at least get you beyond that error.

Does the asset pipeline rails 3.1 waste cycles?

13 votes

In rails 3.1, does .coffee and //= require files get processed only once or with each asset request?

For example,I have a file


//= require source/main.js.coffee
//= require source/second.js.coffee
//= require source/third.js.coffee

Ideally, the server would compile these to js ONCE, then bundle them, then create a static file. But if it happens on each asset requests,it's going to be wasting cycles repeating it??

Thanks for any guidance on this.

Yes, the assets will be compiled AND cached. So they won't generate additional cycles. You can also pre-compile them before you push them to production.

Here is a good writeup: http://blog.nodeta.com/2011/06/14/rails-3-1-asset-pipeline-in-the-real-world/

Mystifying "undefined constant" issue with Ruby/Rails

11 votes

I've got a Rails project where a constant is being nuked at some point while serving a request.

I'm using the mime/types and restclient gems. The restclient module defines an extension to MIME which contains the method type_for_extension.

module RestClient
    ...
    def stringify_headers headers
      result[key] = target_values.map { |ext| MIME::Types.type_for_extension(ext.to_s.strip) }.join(', ')
      ...
    end
  end
end

module MIME
  class Types
    def type_for_extension ext
      candidates = @extension_index[ext]
      candidates.empty? ? ext : candidates[0].content_type
    end
    class << self
      def type_for_extension ext
        @__types__.type_for_extension ext
      end
    end
  end
end

I can access MIME::Types.type_for_extension on my first invocation of a given controller action. On the second invocation, it's gone.

I can still use MIME::Types.type_for, but the added method is simply gone, so when I try to use the RestClient module it throws an exception on the line showin in stringify_headers:

NoMethodError, message: undefined method `type_for_extension' for MIME::Types:Class

**How is this possible? type_for_extension defined in the same file as stringify_headers; how could the latter get nuked but not the former?


EDIT: FIXED IT!

In my config:

config.gem "aws-s3", :version => ">= 0.6.2", :lib => "aws/s3"  
config.gem 'mime-types', :lib => 'mime/types'

aws-s3 was loading mime-types via require_library_or_gem, which ultimate invoked ActiveSupport::Dependencies.autoload_module! which maintains a table called autoloaded_constants which are nuked when ActionController.close calls Dispatcher.cleanup_application.

Fix was to load mime-types first, so it's not autoloaded.

*whew*

Answering my own question by request.

In my config:

config.gem "aws-s3", :version => ">= 0.6.2", :lib => "aws/s3"  
config.gem 'mime-types', :lib => 'mime/types'

aws-s3 library was loading mime-types via require_library_or_gem, which ultimately invoked ActiveSupport::Dependencies.autoload_module! which maintains a table called autoloaded_constants which are nuked when ActionController.close calls Dispatcher.cleanup_application.

Fix was to load mime-types first, so it's not autoloaded.

Repairing Postgresql after upgrading to OSX 10.7 Lion

9 votes

I recently upgraded to OSX 10.7, at which point my rails installation completely borked when trying to connect to the psql server. When I do it from the command line using

psql -U postgres

it works totally fine, but when I try to run the rails server or console with the same username and password, I get this error

...activerecord-3.0.9/lib/active_record/connection_adapters/postgresql_adapter.rb:950:in `initialize': could not connect to server: Permission denied (PGError) 
Is the server running locally and accepting
    connections on Unix domain socket "/var/pgsql_socket/.s.PGSQL.5432"?

Any ideas what might be going on would be super helpful! Thanks!

It's a PATH issue. Mac OSX Lion includes Postgresql in the system now. If you do a which psql you'll likely see usr/bin/psql instead of usr/local/bin/psql which is HomeBrew's correct one. If you run brew doctor you should get a message stating that you need to add usr/local/bin to the head of your PATH env variable.

Editing your .bash_profile or .profile, or whichever shell you're using and adding: export PATH=/usr/local/bin:$PATH

as the first export for the PATH then either quit you shell session or source your file with source ~/.bash_profile and it should now be OK again.

Prawn does not render a PDF on Heroku, but does it local

7 votes

As the title says: My PDFs are perfectly rendered when I run on my server locally, but on Heroku I get a NoMethodError. It seems that Heroku cannot find my prawn gem. I am using the prawn-rails gem.

Any ideas?

I have uploaded the complete callstack here: http://f.cl.ly/items/2g232h3U0B2G0k0i0S1y/Action%20Controller%20%20Exception%20caught.html

Solved. It seems as Heroku does not have a "Helvetica".

Explain to me how config works in Rails

7 votes

I have a Rails 3 application, call it "MyApp". In my config\environments\production.rb file I see such things as

MyApp::Application.configure do
  config.log_level = :info
  config.logger = Logger.new(config.paths.log.first, 'daily')
   ...or...
  config.logger = Logger.new(Rails.root.join("log",Rails.env + ".log"),3,20*1024*1024)

So, questions are focusing on terminology and wtf they mean... (or point me to some site ,I have looked but not found, to explain how this works.)

  1. MyApp is a module?
  2. MyApp::Application is a ...? What, a module too?
  3. MyApp::Application.configure is a method?
  4. config is a variable? How do I see it in console?
  5. config.logger is a ???
  6. config.paths.log.first is a ...?? --in console I can see "MyApp::Application.configure.config.paths.log.first" but don't know what that means or how to extract info from it!?!

Is this too much for one question? :)

I have looked at the tutorial http://guides.rubyonrails.org/configuring.html but it jumps right into what things do.

A six sided question! Oh my. Let's ahem roll.1 Here's hoping I receive 6 times the upvotes for it then? :)

1. MyApp is a module?

Yes, it's a module. It acts as a "container" for all things pertaining to your application. For instance you could define a class like this:

module MyApp
  class MyFunClass
    def my_fun_method
    end
  end
end

Then if someone else has a MyFunClass, it won't interfere with your MyFunClass. It's just a nice way of separating out the code.

2. MyApp::Application is a ...? What, a module too?

MyApp::Application is actually a class, which inherits from Rails::Application. This does a quite a lot of things, including setting up the Rails.application object which is actually an instance of MyApp::Application that you can do all sorts of fun things on like making requests to your application (in a rails console or rails c session). This code for instance would make a dummy request to the root path of your application, returning a 3-sized Array which is just a plain Rack response:

 Rails.application.call(Rack::MockRequest.env_for("/"))

You can also get the routes for your application by calling this:

 Rails.application.routes

The main purpose of defining MyApp::Application is not these fun things that you'll probably never use, but rather so that you can define application-specific configuration inside config/application.rb. Things like what parameters are filtered, the time zone of the application or what directories should be autoloaded. These are all covered in the Configuration Guide for Rails.

3. MyApp::Application.configure is a method?

Indeed it is a method, and it allows you to add further configuration options to your application's configuration after config/application.rb has been loaded. You've probably seen this used in config/environments/development.rb or one of the other two files in that directory, but basically they all use the same options as shown in that Configuration Guide linked to earlier.

4. config is a variable? How do I see it in console?

The config "variable" is actually a method defined within the code used for Rails::Application and returns quite simply a configuration object which stores the configuration for the application.

To access it in the console, just use Rails.application.config. This will return quite a large Rails::Application::Configuration object for your viewing pleasure.

5. config.logger is a ???

The method you're referring to, I assume, comes from this line in config/environments/production.rb:

# Use a different logger for distributed setups
# config.logger = SyslogLogger.new

The method in this example is not config.logger, but rather config.logger=, which is referred to as a "setter" method in Ruby-land. The one without the equal sign is referred to as a "getter". This method sets up an alternative logger for the production environment in Rails, which then can be accessed by using Rails.logger within the console or the application itself.

This is useful if you want to output something to the logs, as you can simply call this code:

Rails.logger.info("DEBUG INFO GOES HERE")

6. config.paths.log.first is a ...?? --in console I can see "MyApp::Application.configure.config.paths.log.first" but don't know what that means or how to extract info from it!?!

Within a Rails application, you can modify the locations of certain directories. And so, this config.paths method is a way of keeping track of where these directories map to. In my entire Rails life I have never had to use or modify this variable and that can mean either one of two things:

  1. It's not used often by Rails programmers, or;
  2. I don't live a very varied life.

Interpret it as you will. My main point is that you're probably never going to use it either.


I hope these help you understand Rails a little more!

1 Terrible dice joke.

How to find out which modules are mixin for a class in Rails?

7 votes

I'm a new Ruby/Rails guy. Here's one question puzzling me:

Can we find the exact module lists mixin-ed for a class in Rails from the API doc? For example, if we have an instance of one subclass of ActiveRecord::Base, we can use validates method in this class such as following:

class Product < ActiveRecord::Base
  has_many :line_items
  validates :title, :description, :image_url, :presence => true
end

from rails api doc we can find that validates belongs to ActiveModel::Validations::ClassMethods, so ActiveRecore::Base must have ActiveModel::Validations::ClassMethods mixin, but I didn't find anything relating to this in the api reference. Can anyone tell me if I can find this info from api doc?

Thanks for all of your help in advance. I really hope my question doesn't sound too silly:)

I don't see anything like that in any of the Rails documentation I've seen:

And with monkey patching, there probably isn't any way to know until Rails is all cranked up and you have an actual ActiveRecord::Base in your hands; for example, the PostgreSQL, MySQL, and SQLite adapters re-open ActiveRecord::Base and they might include extra modules along the way; other gems you're using and even your own code may do similar things.

If you just want to know the standard set of mixins, use the source (Luke!) or do as maniek suggests and ask ActiveRecord::Base in the Rails console.

In general, the Rails API documentation isn't that useful unless you already know what you're looking for and even then, digging into the source is often necessary.

Your best bet is to check the guides for what you need and read the source if that doesn't work.


Short Answer: You can't get your list from the documentation because the modules cannot be known until run time. Read the guides and the source if you need to know something.

What is the "rails way" to enforce a has_many but has-only-one-current association?

6 votes

I have a simple rails app with models project and phase. A project has many phases, but only on phase can be active (i.e. "current") at a time. I still want the other phases to be accessible, but the current phase should be the main anchor for the application. The decision on how to implement this requirement has major implications on how I handle model access, validations and views / forms for creation update.

So the question is: How do I achieve this "has_many but has-only-one-current association" without adding too much complexity? Main goals being: simplicity in access of current phase + ensuring there cannot be more than 1 active phase at a time.

Naturally, I had some thoughts myself and came up with three options, which I want to present here. Any feedback on why I should choose one option over the other (or suggestion of a simpler solution) would be appreciated:

First Option:

[Project] has_many :phases
[Project] has_one  :current_phase, :class_name => "Phase", :conditions => { :current => true }

Drawback: I have a nested form for creating projects and corresponding phases. There seems to be no easy way to set exactly one of the newly created phases as active

Second Option:

[Project] has an attribute "current_phase_id"

[Project] has_many :phases
[Project] belongs_to phase, :foreign_key => "current_phase_id"

Drawback: same as option 1, but I have another attribute and a belongs_to association, which seems weird (why should a project belong to one of its phases?)

Third Option:

[Phase] has an attribute "active" (boolean)
[Phase] scope :active, :conditions => { :active => true}

# Access to current phase via: project.phases.active

Drawback: I have to ensure via validations that there is only one active phase at a time, which is hard if multiple phases are created / edited at the same time OR during switch from one phase to another; plus: project.phases.active returns an array, if I'm not mistaken

Your help is greatly appreciated. Thanks!

Update

Added a bounty to encourage further opinions on the topic. Bounty will be awarded to the solution which best addresses the main goals expressed above; or if no alternative solution is mentioned, to the answer that best explains why I should favor one of the given options over the other. Thanks!

Why don't you just add a date-time column called activated_at to your Phase model. Then set this to the current time whenever you want to make a phase active.

At any given time, the phase with the latest activated_at value is the current phase so you can just get it with @project.phases.order('activated_at DESC').first. Just wrap this in a method in Project and you have a very concise representation:

# in project.rb
def current_phase
  phases.where("activated_at is NOT NULL").order('activated_at DESC').first
end

How do you write DRY, modular coffeescript with Sprockets in Rails 3.1?

6 votes

I'm in the early stages of trying to write some sensible Javascript. I want to namespace basically everything under the name of my application to avoid globals as much as possible, but still give me a way to access functions declared around the place. However, I don't want to be super verbose in my function definitions.

My ideal CoffeeScript would be something like this:

class @MyApp
  @myClassMethod = ->
    console.log 'This is MyApp.myClassMethod()'

  class @Module1
    @moduleMethod = ->
      console.log 'This is MyApp.Module1.moduleMethod()'

You get the picture. This way I avoid having to write MyApp.Module.submoduleMethod = -> every time I want to define a namespaced function properly - using @ and defining things within my class definition keeps things nice and short.

This is all going well until I want to split my functionality up into multiple CoffeeScript files. Then what I really want is something like this:

// application.js
class @MyApp
  //= require 'module1'
  //= require 'module2'

// module1.js
class @Module1
  @moduleMethod = ->
    console.log 'This is STILL MyApp.Module1.moduleMethod()'

It doesn't seem like Sprockets can do this.

Is there a sensible way to require my CoffeeScript files in the right place in my container files? Or another way to approach writing modular code that is divided into separate files using CoffeeScript, Sprockets and Rails 3.1?

I have a module solution that I use in my code.

I define my modules like below

@module "foo", ->
    @module "bar", ->
        class @Amazing
            toString: "ain't it"

Amazing is available as

foo.bar.Amazing

implementation of the @module helper is

window.module = (name, fn)->
  if not @[name]?
    this[name] = {}
  if not @[name].module?
    @[name].module = window.module
  fn.apply(this[name], [])

It's written up on the coffeescript website here.

https://github.com/jashkenas/coffee-script/wiki/Easy-modules-with-coffeescript

Create a simple Rails 3 text helper Gem

5 votes

I've been working on my first Rails 3 plugin, to package up a simple helper function that I like having in the ApplicationHelper of all my apps. You can see the whole code on Github.

Here's my first attempt:

## lib/semantic_id.rb ##

require 'semantic_id/version'

module ::ActionView::Helpers::TextHelper

  def semantic_id
    string = String.new

    case
    when controller.action_name =~ /new|edit/
      string += controller.action_name + "_"
    when controller.action_name =~ /index|create/
      string += controller.controller_name
    else
      string += controller.controller_name.singularize
    end

    string += "_view"
  end

end

Now, this works, but as I understand it this is not the 'Rails 3 Way' of extending ActiveSupport or any other Rails module. I haven't been able to find much documentation on how you're "supposed" to build a Rails 3 gem. I tried following the Rails Guide, but the method given there for adding helpers didn't work, or else I was missing something.

My question is: given the code above as an example of the functionality I'm looking for, how would you turn this into a Rails 3 plugin Gem?

Thanks!

I asked a similar question here How do I extract Rails view helpers into a gem?

and went with this code here https://github.com/sid137/placehold

http POST error

5 votes

I'm trying to send the xml to another webserver through Restclient's http POST request.This is the code :

response =  RestClient.post 'https://secure.rowebooks.co.uk/testorders/orders.aspx', :content_type => "text/xml", :myfile => File.read("#{Rails.root}/public/shared/#{@book}.xml")

But I'm getting this error

ERROR 2 Data at the root level is invalid. Line 1, position 1.ERROR3 Object reference not set to an instance of an object.

I've been told that I am receiving that error because the XML file is not in the content of the call. It must be in the content. I have no idea what does this mean.

Any suggestion / clue will be greatly appreciated.

Thanks

You should be doing it like this:

response =  RestClient.post( 'https://secure.rowebooks.co.uk/testorders/orders.aspx', 
File.read("#{Rails.root}/public/shared/#{@book}.xml"), 'Content-Type' => 'text/xml' )

dynamic URLs in java web application (like in rails)

5 votes

I'm a Ruby on Rails developer programming a web application in Java. I am trying to achieve something similar to what is achieved in Rails. In Rails it is possible to call a link using localhost:8000\Users\1 when Users is a Model and 1 is the id of a specific user. I would like to get the same kind of thing in Java.

I am working in an MVC type design where my JSP pages are the view and my Servlets are the controllers. I created a servlet called Users which renders the users.jsp page now i can get to that page using the URL localhost:8000\projectName\Users, i would like to route localhost:8000\projectName\Users\1 to the page user.jsp while the appropriate Servlet will handle sending into the page the correct user (with id=1).

Any idea how I can achieve this?

I'm doing this in a University project and am not allowed to use any frameworks. I also would rather something i could code rather than install.

now i can get to that page using the URL localhost:8000\projectName\Users, i would like to route localhost:8000\projectName\Users\1 to the page user.jsp while the appropriate Servlet will handle sending into the page the correct user (with id=1).

Simple. Map the servlet on an URL pattern of /Users/* instead of /Users. You can then grab the path info (the part after /Users in the URL, which is thus /1 in your example) as follows:

String pathInfo = request.getPathInfo();
// ...

You can just forward to users.jsp the usual way.

Long id = Long.valueOf(pathInfo.substring(1));
User user = userService.find(id);
request.setAttribute("user", user);
request.getRequestDispatcher("/WEB-INF/users.jsp").forward(request, response);

Side effects of redefining $stdout and $stderr in a Rails app

5 votes

I'd like to temporarily redirect $stdout and $stderr to a file in a script that will be run by script/runner in a Rails app. Are there any potential side effects to doing so? Will changing the global variable cause the output streams to be redirected in other parts of the Rails application during the duration of my script? What about other libraries or threads used by the script?

The standard output and standard error streams are generally accessible in two ways each:

  • $stdout and STDOUT
  • $stderr and STDERR

A sufficiently clever person could also open their own copies using IO.new with a file descriptor argument:

sneaky = IO.new(2, 'w')

And now you have writable access to the standard error stream through sneaky without having anything to do with $stderr or STDERR.

Reassigning $stderr and $stdout should work fine unless something in your code, your gems, or Ruby itself is using the constants (STDOUT, STDERR) or is accessing the streams directly through C's stdio, unix's low level read/write with numeric file descriptors or is opening their own access to the streams using IO.new. I haven't dug into the source but I doubt assigning to $stdout will do anything to stdout in C-land or file descriptor 1 in Unix-land.

If you really need to trap the standard output and error streams then you're probably better off writing a wrapper shell script to redirect the streams for you.


UPDATE: If you're mostly (only?) concerned about changing $stdout and $stderr inside your script/runner bleeding into the rest of your Rails app then you don't have to worry about that. Each process — your script/runner process and however many server processes your main application has running — gets its own set of globals so you can change them all you want in your script without making a mess of your main application. Of course, you still have to worry about gems using STDOUT instead of $stderr or using IO.new to get their own private standard out.

Why do RoR professionals NOT use Scaffolding?

5 votes

I read sometimes from people that seem to be working with rails since longer, that one important lesson they learnt would be "Don't use scaffolding". Also on irc I read commonly hints from this direction. My question is why, what is the bad thing about it? And is nifty_scaffolding bad as well?

My guess would be it is bad because it generates by default an xml version of your controller action, which would expose the field names of our application to anybody and make it more vulnerable for attacks, so maybe it's this?

What are your reasons to not do scaffolding?

I'm experienced with rails and I rarely use scaffolding simply because my end goal is far from simple crud actions. However, there's no strict rule to not use scaffolding. The reason some people frown on it is that it is actually scaffolding, literally. Too many newbies like to push scaffolding to the production server thinking it is production ready. Scaffolding is just a jump start to an end goal.

5 votes

I'm not sure I understand this syntax error. I'm using Carrierwave to manage some file uploads in a Rails app, and I seem to be passing a block to one of the methods incorrectly.

Here's the example in the Carrierwave Docs:

version :thumb do
  process :resize_to_fill => [200,200]
end

Here's what I had:

version :full   { process(:resize_to_limit => [960, 960]) }
version :half   { process(:resize_to_limit => [470, 470]) }
version :third  { process(:resize_to_limit => [306, 306]) }
version :fourth { process(:resize_to_limit => [176, 176]) }

The above doesn't work, I get syntax error, unexpected '}', expecting keyword_end. Interestingly enough, the following works perfectly:

version :full   do process :resize_to_limit => [960, 960]; end
version :half   do process :resize_to_limit => [470, 470]; end
version :third  do process :resize_to_limit => [306, 306]; end
version :fourth do process :resize_to_limit => [176, 176]; end

So, my question is, why can I pass a block using do...end but not braces in this instance?

Thanks!

Try this:

version(:full)   { process(:resize_to_limit => [960, 960]) }
version(:half)   { process(:resize_to_limit => [470, 470]) }
version(:third)  { process(:resize_to_limit => [306, 306]) }
version(:fourth) { process(:resize_to_limit => [176, 176]) }

You have a precedence problem. The { } block binds tighter than a do...end block and tighter than a function call; the result is that Ruby thinks you're trying to supply a block as an argument to a symbol and says no.

You can see a clearer (?) or possibly more familar example by comparing the following:

[1, 2, 3].inject 0  { |x, y| x + y }
[1, 2, 3].inject(0) { |x, y| x + y }

One controller for multiple routes

5 votes

I've been searching for a while now, but I can't seem to figure out if this is even possible. What I need is one controller for two different paths.

What I have is one model, with two types: own and compatitive.

So what I want is two paths like this, going both to one controller:

example.com/hotels

example.com/compatitives

These have to be resources, and there is going to be a lot of nesting in these routes. So I don't want to create a resource mapping for both of them.

I've already tried this:

resources :hotels, :compatitives, :controller => :hotels do

  resources :rooms do
    collection do
      match "/search", :action => :search
    end
  end

  collection do
    match "/search"
    match "/results/:type/:id(/:page)", :action => :results
  end

end

resources :prices do
  collection do
    match "/check"
  end
end

But the controller is not hotels_controller for both.

Is this even possible?

Thanks!

Got it to work with this solution:

def add_hotel_collection
  resources :rooms do
    collection do
      match "/search", :action => :search
    end
  end
  collection do
    match "/search", :action => :search
    match "/results/:type/:id(/:page)", :action => :results
  end
end

resources :hotels do
  add_hotel_collection
end

resources :compatitives, :controller => :hotels do
  add_hotel_collection
end

Make a custom helper available to both Mailer and View in Rails 3.1

4 votes

is this the best way to make a helper available to both Mailer and view in Rails 3.1?

class EventMailer < ActionMailer::Base
  include MailerHelper
  helper :mailer

I tried

helper :mailer

on its own, but that didn't allow me to use the helpers in the EventMailer class.

I tried

add_template_helper(MailerHelper)

but had the same problem.

The rails helpers are supposed to be view helpers.

You will notice that the following code :

class MyController < ApplicationController
    helper :my
end

will make the methods in MyHelper available to the views, but not to your controller actions. include MyHelper will make the helper methods available in the controller.

Summarized :

helper :my and you can use the helpers in your views

include MyHelper and you can use the helpers in your controller

I explained a bit more, but you already answered your question :

class EventMailer < ActionMailer::Base
    include MailerHelper
    helper :mailer

    # rest of the code goes here ...
end

will do what you want and allow you to use your helper in both your mailer and your views.

Hope this helps.

A folder where to put "global" shared partial templates

3 votes

I am using Ruby on Rails 3.0.7 and I am planning to use partial templates. All classes in my application would use same partials so I have to decide where to located all those.

Is it a good idea to put "global" shared partial templates in the lib folder? If no, what is a common practice to choose the folder where to put those? Any advice on how to properly name and load that folder?

The standard is placing all shared partials in app/views/shared, and referencing them as

render :partial => 'shared/partial_name'

If you have a standard "row in a list" partial (say, for an index page), you could use a shared partial like:

# To render a single object row:
render :partial => 'shared/item', :locals => { :item => @item }
# Or to render them all:
render :partial => 'shared/item', :collection => @items

Rails, in the model is there a way to provide a dif since the last update?

3 votes

given a model like:

class SentenceItem < ActiveRecord::Base

  after_update :send_changes

  def send_changes
     #### Is it possible to do a diff here with dirty/changed? Showing what's changed since the last save?
  end

end

And that the sentence modle has a text field.

Is it possible to do a diff here with dirty/changed? Showing what's changed since the last save?

Thanks

Yes, there is a way. From the ActiveModel::Dirty documentation:

A newly instantiated object is unchanged:

person = Person.find_by_name('Uncle Bob')
person.changed?       # => false

Change the name:

person.name = 'Bob'
person.changed?       # => true
person.name_changed?  # => true
person.name_was       # => 'Uncle Bob'
person.name_change    # => ['Uncle Bob', 'Bob']
person.name = 'Bill'
person.name_change    # => ['Uncle Bob', 'Bill']

Which attributes have changed?

person.name = 'Bob'
person.changed        # => ['name']
person.changes        # => { 'name' => ['Bill', 'Bob'] }