RailsCasts Pro episodes are now free!

Learn more or hide this

Recent Comments

Avatar

I found a solution on StackOverflow. By appending constraints: { id: /.*/ } to the get route, so it reads:

ruby
get ':id', to: 'pages#show', as: :page, constraints: { id: /.*/ }

it now recognizes routes to pages with slashes in their permalinks like "about/jobs". I guess Rails has its own constraints (like no slashes) on id's that this overrides.

Avatar

This is an absolutely ASTOUNDING tutorial/runthrough - one of the best I've ever come across on anything Rails-related. I will admit it took me around 2 days involving a couple of attempts and a bit of debugging to get everything working, but I got there in the end.

From memory, the main issues I had to deal with were as follows:

1) As Steve Fox mentions above, you will probably need to edit the /etc/nginx/sites-enabled/default file as per Steve's instructions in order to get nginx to work properly.

2) For some reason, when I tried to install PostgreSQL, version 8 was installed on my server, whereas version 9 appears to be installed in the video for Ryan's installation. I had to make sure I added this to the relevant command in the terminal. From memory (so you might want to check), it was:

ruby
apt-get install postgresql-9.2 libpq-dev

(Or whatever the current version is at the point you are reading this :-) ). See also this link.

3) An obvious one, but make sure that you install the same versions of Rails, PostgreSQL etc. on your server that you have on your local machine!

4) If your gems fail to install properly on the server, you may need to install the relevant development files:

ruby
sudo apt-get install libxslt-dev libxml2-dev

See this StackOverflow question/response, and particularly the response with the most upvotes for further info.

HOWEVER, the most important piece of advice I can give based upon my experiences is as follows:

If you're intending to deploy your first ever app, do not build your complete app locally and then attempt to deploy it. There are probably minor differences in the different installations which are likely to cause your 500 page to appear, and which may end up being a nightmare to debug.

Instead, my advice would be to set up your server as soon as you write the first line of code for your app (even if it's just a "Hello World!") - and then deploy and debug as you go along. Believe me, this saves the frustration (particularly if you're a novice and not quite sure of what you're doing) of having a complete, working app on your local machine and one that refuses to work on a server. If you carry out a staged deployment, any issues should be identifiable and therefore rectifiable fairly quickly, rather than trying to debug a complete app at the end of the process. If you're worried about having an unfinished app publically available, I suppose you could set a username/password using the nginx equivalent of Apache's htpassword (do a Google search) to the root directory so that visitors to your site won't be able to access it.

Hope this helps others - and thanks again, Ryan!

Avatar

Any thoughts on nesting pages like this? Specifically, say I want an About page at "/about" and a Jobs page at "/about/jobs". I've tried setting the permalink for the jobs page to be "about/jobs", but Rails doesn't recognize this route.

Avatar

why can't i access http://127.0.0.1:3000/assets/applications.js
its show me

Routing Error

No route matches [GET] "/assets/applications.js"

Avatar

I'm the author of the Apartment gem that's referenced here. We've been using it for over a year on Heroku and it utilizes schemas.

It's definitely fine to use, we still get great performance with well over 100 schemas in an application with 50+ tables per schema.

The article mentioned by @4ware talks about issues with heroku's pg:backups command. (I'm pretty sure that article came about from our support queries to them)

It DEFINITELY has issues, but this is not a shortcoming of Postgresql, schemas or multi-tenancy with schemas, but rather the heroku tool itself. Now that Postgresql has ingres support on their dbs, you don't really need to use their built in tools. We just pg_dump when we need to and it works just as fast as one would expect.

Avatar

If you're having trouble with Pow and environment variables, be sure to store them in .powrc in your project root.

Avatar

how to search by single character using solr sunspot

Avatar

With this set up, how can I determine the max number of tenants that can be supported on a single server? How to test this out?

Avatar

Just a heads up:

After installing gem, and adding 'acts_as_list' to your model you might get this error...

undefined method `key?' for nil:NilClass

..if you don't restart the server.

Avatar

Did you ever figure this out? Trying to do the same thing. Thanks!

Avatar

I'm also curious about this. If we're not supposed to keep config data in SCM, where does it go?

Avatar

Im using rails 3.2 and the ajax doesn't work for me

i got this error Uncaught SyntaxError: Unexpected identifier

in

$.get($('#playlists_search').attr('action'), ↵
$('#playlists_search').serialize(), null, 'script');
return false;

Avatar

OK guys, please ignore this comment.

The whole thing is more complicated than I thought.
Two issues:
1. It seems that making an Account (or Tenant) controller confuses the picture.
2. Has anyone handled the situation where the subdomain is not present ?

Avatar

I'm having a bit of an issue with this. I am using 'Account' rather than 'Tenant' but otherwise everything is as the example.
When I do 'db:migrate --trace' the first time I get -
'
** Invoke db:migrate (first_time)
** Invoke environment (first_time)
** Execute environment
** Invoke db:load_config (first_time)
** Execute db:load_config
** Invoke multiaccount:db:migrate (first_time)
** Invoke environment
** Invoke db:load_config
** Execute multiaccount:db:migrate
rake aborted!
PG::Error: ERROR: relation "accounts" does not exist
LINE 4: WHERE a.attrelid = '"accounts"'::regclass
^
: SELECT a.attname, format_type(a.atttypid, a.atttypmod), d.adsrc, a.attnotnull
FROM pg_attribute a LEFT JOIN pg_attrdef d
ON a.attrelid = d.adrelid AND a.attnum = d.adnum
WHERE a.attrelid = '"accounts"'::regclass
AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum
...
'

Has anyone else encountered this issue ?

Avatar

Dean, could u solve this issue? I'm having the same one :(

Avatar

What is the "key" attribute? It's neither a column in Paintings nor attr_accessor but we still can access it with Painting.first.key in the console. Pretty weird to me.

Avatar

I was wondering about Time.use_zone resp Time.zone in a threaded environment
(like torquebox/jruby).

If I interpret the documentation correctly, then Time.zone is a thread local
variable, which means it will just work fine. Can somebody confirm this?

Also the docu reads that Time.zone is a per request value (in mri). However,
that would mean that you actually don't need to use an around filter. A before
filter should suffice, doesn't it?

Avatar

I fixed the problem by adding this:

ruby
  task :setup do
    run "mkdir -p #{shared_path}/config"
    template "application.yml.erb", "#{shared_path}/config/application.yml"
  end
  
  before 'deploy:assets:precompile' do
    run "ln -s #{shared_path}/config/application.yml #{release_path}/config/application.yml"
  end

woo :)

Avatar

How did you do it?

I have this in my deploy recipe:

ruby
    run "mkdir -p #{current_path}/config"
    run "mkdir -p #{release_path}/config"
    run "mkdir -p #{shared_path}/config"
    template "application.yml.erb", "#{current_path}/config/application.yml"
    template "application.yml.erb", "#{release_path}/config/application.yml"
    template "application.yml.erb", "#{shared_path}/config/application.yml"

When I do cap deploy:setup, it copies the file to:

ruby
    /home/deployer/xanview-portals/demo1/current/config/application.yml
    /home/deployer/xanview-portals/demo1/releases/20121031020720/config/application.yml
    /home/deployer/xanview-portals/demo1/shared/config/application.yml

But when I do cap deploy:cold I see:

ruby
    2012-10-31 02:08:20 executing `deploy:assets:precompile'
    executing "cd /home/deployer/xanview-portals/demo1/releases/20121031020819 && bundle exec rake RAILS_ENV=production RAILS_GROUPS=assets assets:precompile"
    servers: ["zanview.com"]
    [zanview.com] executing command
    [out :: zanview.com] rake aborted!
    [out :: zanview.com] No such file or directory - /home/deployer/xanview-portals/demo1/releases/20121031020819/config/application.yml

And it dies :( - Any ideas?

Avatar

Get the following error when I try to sign in with twitter:

NoMethodError in OmniauthCallbacksController#twitter

undefined method `username=' for #User:0x007fc48595d160

Any help would be awesome!

Avatar

Hello,

I followed all the steps, and when I visit the ip address ( or domain name set in hosts ) I get apache server's default page "It works". I did not get rails app.

I have an EC2 tiny instance with ubuntu 12.04 in it.

Please help.

Avatar

For details that are not covered in the RailsCast, take a look at the open source example application for a Rails Membership/Subscription/SaaS Site from the RailsApps project. It comes with a tutorial that goes into detail about how to integrate Stripe with Devise, shows how to use Stripe webhooks, and explains the implementation in detail.

Avatar

But there are no hoops.
You install this gem and it does the work for you.

Avatar

Keep in mind that if you do things in a different ruby process (e.g. background jobs) you need to set the correct timezone there too.

Avatar

try

_condition_fields.html.erb
<%= f.predicate_select({only: [:eq]}) %>
Avatar

Did anyone experience a problem with using Thread.current store in a default scope? When i change the ID stored in Thread.current i can see that it is overwritten but the default scope query stays intact - like it was cached with the previous ID. Can i get rid of that cache from default scope? The alternative is to use a scope with a parameter, but then it doesn't make sense to use Thread.current for storing current tenant ID simply because it can be stored i current_user.* (whatever).

Avatar

Can anyone point me in the right direction? I want to allow a user to only show, edit, update, or destroy their own user resource? I've implemented the @current_user caching from rails cast #274 Remember Me & Reset Password

application_controller.rb
private 
  def current_user
    @current_user ||= User.find_by_auth_token!(cookies[:auth_token]) if cookies[:auth_token]
  end
def current_resource
    nil
  end
  
  def authorize
    if current_permission.allow?(params[:controller], params[:action], current_resource)
      current_permission.permit_attr! params
    else
      if current_user
        flash[:alert] = 'Not Authorized'
        redirect_to home_path
      else
        session[:protected_page] = request.fullpath
        flash[:alert] = 'Please Login'
        redirect_to root_url
      end
    end
  end
member_permission.rb
module Permissions
  class MemberPermission < BasePermission
    def initialize(user)
      allow :sessions,        [:new,:create,:destroy]
      allow :password_resets, [:new,:create,:edit,:update]
      allow :users,           [:new,:create]
      allow :users,           [:show,:edit,:update,:destroy] do |current_user|
        current_user.id == user.id
      end
      allow :interests,       [:new, :create]
      allow :interests,       [:edit, :update, :destroy] do |interest| 
        interest.user_id == user.id 
      end
      allow_attr :user,       [:email, :zip_code]
    end
  end
end

I get caught in an infinite redirect loop when a normal user tries to show their own user profile. Any tips or suggestions would be appreciated. Mahalo

Avatar

Got a question here.
I tried to follow the tutorials and when I got to the step:

$(document).ready{
$('.edit_task input[type=submit]').remove();
$('.edit_task input[type=checkbox]').click(function() {
$(this).parent('form').submit();
});
});

It just does not work for me.... i tried to find out why using the checklist-after version and that would not work as well... any thoughts on why this is happening ????

Avatar

If you want to get a time with a specific time zone, you can do:

ruby
ActiveSupport::TimeZone.new("Asia/Tokyo").local(2012, 1, 1)  # => Sun, 01 Jan 2012 00:00:00 JST +09:00
Avatar

Thank god, I was not getting any results back.

Avatar

You aren't caching the lists themselves, just the individual objects.
When you setup your associations you do the ":touch => true" option so the related object gets touched, thus automatically expiring the cache on it.

Avatar

Im getting an error on the validation server side... in fact Im not getting the error alert when the name is not present.

im using rails 3.2.8 and backbone-on-rails 0.9.2.3

In the network console it does state that theres an error with the api/entries, and in the response theres the errors key, but still no alert..

Avatar

Well I would like to mention that episode 389 is about using schemas with PostgreSQL, so far I have read you are using mongodb and I would like to know what you were using before.

Avatar

What about deploying your app when the application.yml isn't part of your code in git? When working with different developers it's a pain in the ass to keep the application.yml for the production env in sync. Any tips on this one?

Avatar

Yep!

Even starting to wonder if N+1 issues can be mitigated with fragment caching instead of always having the server do the include at the action.

Avatar

I am getting an error after allowing permission in the dialog. It looks like Facebook is routing the callback to an SSL page, which my localhost is not configured to handle.

The error:
Faraday::Error::ConnectionFailed

SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed

Does anyone know how I can get the callback to force a non-secure URL?

Avatar

Heroku PG databases do support schemas, although I have been through it a bit with some of the tech there, and a couple of their internal tools (for example, pg:dump) for some reason slow down to unreasonable speeds, so YMMV. If you have a few large clients, I assume it would be fine, but I think lots of smaller clients (according to Heroku, lots being more ~ 20), you would be better off using the join method.

Avatar

Yay! I wrote that Devise wiki page last week, I am glad somebody found it :)

Avatar

This episode will help solidify a lot of testing headaches. We're currently using javascript to manipulate time zones but I think this episode provides great in depth insight into how to manipulate time zones for testing. Thanks Ryan.

Avatar

I notice the same issue. Endless queue that kills my database performance.
What's the better way to avoid this?

Avatar

Thanks for the tip!

I was using this settings logic: http://speakmy.name/2011/05/29/simple-configuration-for-ruby-apps/

Bad thing is, they aren't always loaded, I had some cases in the workers where the Settings weren't actually available.

Avatar

"That’s it for this episode on PayPal. It was longer than usual but it’s still not feature complete as we need to handle customers who have insufficient funds or who cancel their subscriptions. These may be covered in a future episode."

PLEASE RYAN, COVER IT :D