Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
UxP
Aug 27, 2007
Are you trying to create the base, db backed object as "Record", and then namespace it's children under it, like this?

Ruby code:
class Widget < ActiveRecord::Base
  attr_accesible :name

end

class Widget
  class Twirlymajig < Widget
    attr_accessible :sprockets

  end
end
This is technically valid ruby code from what I understand, my co-worker just said I'm wrong. Inheriting from your parent is not valid, but it will manage to run on some occasions. Most specifically, you're always required to load the full base class first, else Rails will complain about the child class not defining it's constant in the global space because the first class declaration in the file doesn't match the inflected file name, and then once you resolve that, you'll end up with the parent class being treated as a module on some occasions.

You'd have better luck defining a base class inside a module and inheriting all your children from that.
Ruby code:
# in app/models/widget.rb
module Widget
  # base namespace for Base, Twirlymajog, and Sprocket,
end

# in app/models/widget/base.rb
module Widget
  class Base < ActiveRecord::Base
    attr_accessible :name

  end
end

# in app/models/widget/twirlymajig.rb
module Widget
  class Twirlymajig < Base
    attr_accessible :sprockets

  end
end

UxP fucked around with this message at 00:20 on Apr 13, 2013

Adbot
ADBOT LOVES YOU

Lexicon
Jul 29, 2003

I had a beer with Stephen Harper once and now I like him.
I've got an ActiveRecord model with an metadata field that I'd like to be a hash in ruby-land, but be serialized to the database as JSON. Ideally, this conversion would all be handled nicely by before_save hooks and so forth.

What's the best way to go about this?

UxP
Aug 27, 2007

Lexicon posted:

I've got an ActiveRecord model with an metadata field that I'd like to be a hash in ruby-land, but be serialized to the database as JSON. Ideally, this conversion would all be handled nicely by before_save hooks and so forth.

What's the best way to go about this?

Depends on which version of ActiveRecord you're using, but you should be able to do this with >= 3.1

Ruby code:
class Post < ActiveRecord::Base
  serialize :metadata, JSON

end
Otherwise, here's a Gem I've recently converted from an old plugin to do the same thing, but with Marshal data instead of JSON. The idea should be identical: https://github.com/uxp/marshalled_attributes

Lexicon
Jul 29, 2003

I had a beer with Stephen Harper once and now I like him.
^^ Perfect, thanks!

Edit: What about making the attribute a HashWithIndifferentAccess on deserialize, not just a regular Hash?

Lexicon fucked around with this message at 18:19 on Apr 22, 2013

mcw
Jul 28, 2005
Is this thread appropriate for Ruby questions that aren't focused on Rails?

If so: I'm new to Ruby, and as a learning project I'd like to do something with Rack. Ruby seems to have a nice ecosystem for infrastructure-as-code, but I'm not sure what is the most commonly-used web server configuration for folks using Rack but not Rails. Do folks usually start up servers using Thin and then tie them in to nginx using sockets, or...? I'm curious what most folks do (assuming they're self-hosting, or at least not using Heroku).

Vulture Culture
Jul 14, 2003

I was never enjoying it. I only eat it for the nutrients.

MariusMcG posted:

Is this thread appropriate for Ruby questions that aren't focused on Rails?

If so: I'm new to Ruby, and as a learning project I'd like to do something with Rack. Ruby seems to have a nice ecosystem for infrastructure-as-code, but I'm not sure what is the most commonly-used web server configuration for folks using Rack but not Rails. Do folks usually start up servers using Thin and then tie them in to nginx using sockets, or...? I'm curious what most folks do (assuming they're self-hosting, or at least not using Heroku).
There's lots of Rack-based frameworks out there in wide use, particularly Sinatra, but the whole idea of Rack in the first place is that it's supposed to make deployment methodologies for "Rails" versus "not Rails" irrelevant. Infrastructure-as-code also isn't of any particular importance or relevance to the question you're asking.

If your core question is "how should I host my Rack application?" your first answer should be "whatever's easiest" and your second answer should be "whatever will help scale my app to where it needs to be" after the the first answer stops being good enough. Thin and Unicorn are the two most popular Rack servers these days, and the dichotomy generally breaks down as follows: if you want something that's really easy to get working, use Thin, and if you need to squeeze every drop of performance out of your application, use (and hand-tune) Unicorn. Passenger is still a good option if you have some application that mostly sits idle and can be spun up on demand the first time a user hits it.

For internal applications where you're not dealing with high request throughput, if you wanted to keep configurations really simple you could probably get away with just running the app server and not front-ending it with something like Nginx at all. A frontend web server will give you the following benefits, though:

  1. Caching, significantly faster asset serving
  2. A more feature-complete HTTP implementation (easily set custom headers, etc.)
  3. Useful log formats
  4. Much more flexibility in configuration (URL rewrites and so forth)
  5. Thin and Unicorn aren't going to do SSL for you

You have the option of using Unix sockets or proxying to the app server over TCP. In synthetic benchmarks, Unix sockets are faster, but in practice, the performance difference is generally negligible unless you're operating at insane scale.

mcw
Jul 28, 2005
Thank you very much! That's a very useful answer.

KoRMaK
Jul 31, 2012



How do I specifiy the namespace (not sure what to call it in ruby or rails, I'm using it as if this were java or C#) of a variable I am using? I have a local variable that is getting in the way of a similar one in a module. Is there a way I can delineate between the two?

I have had the same problem with a definition in the application helper override a model's scope definition.

Similar problem, I have overridden I18n.t in my application helper but when I try to call it from the application helper file it uses the default I18n.t version instead of the one I wrote. Doing ApplicationHelper.t gets me the right one, but it loses the context of my current_account variable which I need t to be aware of.

KoRMaK fucked around with this message at 16:56 on Apr 23, 2013

mmachine
Jan 5, 2006
Having an issue with a form_for on a routes resource and Rails' automatic pluralization. I have a definition in my routes.rb that goes like this:

pre:
resources :magic_fives
...and then a form for that goes like:

pre:
form_for @magic_five ...etc
This works just fine on the create / new form, but I've discovered that the route it's expecting on an edit for the plural of 'magic_fives' is actually 'magic_fife', according to rake:routes. So, I'm interested in the best method of either getting my form_for to generate the proper route -- magic_fife, but I don't think a form_for will generate routes dynamically like that... -- OR define that route resource so it builds the expected routes to be what I thought they would be -- magic_five(s).

I've researched this a bit already, and I see it's a consistent bug in Rails 3 regarding route :resource definitions automagically being pluralized. What I'm curious about is the most efficient way of addressing it. Has anyone had to deal with this before?

The Journey Fraternity
Nov 25, 2003



I found this on the ground!

mmachine posted:

Having an issue with a form_for on a routes resource and Rails' automatic pluralization. I have a definition in my routes.rb that goes like this:

pre:
resources :magic_fives
...and then a form for that goes like:

pre:
form_for @magic_five ...etc
This works just fine on the create / new form, but I've discovered that the route it's expecting on an edit for the plural of 'magic_fives' is actually 'magic_fife', according to rake:routes. So, I'm interested in the best method of either getting my form_for to generate the proper route -- magic_fife, but I don't think a form_for will generate routes dynamically like that... -- OR define that route resource so it builds the expected routes to be what I thought they would be -- magic_five(s).

I've researched this a bit already, and I see it's a consistent bug in Rails 3 regarding route :resource definitions automagically being pluralized. What I'm curious about is the most efficient way of addressing it. Has anyone had to deal with this before?

Try tossing this in an initializer:

code:
ActiveSupport::Inflector.inflections do |inflect|
  inflect.irregular 'magic_five', 'magic_fives'
end

mmachine
Jan 5, 2006

The Journey Fraternity posted:

Try tossing this in an initializer:

code:
ActiveSupport::Inflector.inflections do |inflect|
  inflect.irregular 'magic_five', 'magic_fives'
end

Oh very nice -- thanks! Exact type of solution I was looking for.

mmachine
Jan 5, 2006
Ok, more fun with the magic_five model. This might not be the most graceful relationship, but in this magic_five model there are five fields, each of which points to a record of the same TYPE of model, but not the same model. So it's like:

magic_five.potion_1
magic_five.potion_2
magic_five.potion_3
magic_five.potion_4
magic_five.potion_5

...but each of the potion_% fields points to a record in my potions table. What I'd like to (try) to do is define my magic_five model to know that each of those fields is a corresponding potion record, so I could hit it like:

magic_five.potion_1.potion_name

So far these relationships have been drawn explicitly with manual querying -- now I'm at a point where it could be helpful to give them a more robust relationship in my magic_five.rb model. The first attempt I gave at this looked something like:

has_many :potions, :primary_key => :potion_1, :foreign_key => :id

Which doesn't work, but I'm not sure what piece I'm missing.

prom candy
Dec 16, 2005

Only I may dance
With the way you've got it set up you would use something like:
code:
belongs_to :potion_1, :class_name => "Potion"
belongs_to :potion_2, :class_name => "Potion"
belongs_to :potion_3, :class_name => "Potion"
belongs_to :potion_4, :class_name => "Potion"
belongs_to :potion_5, :class_name => "Potion"
This probably isn't the best way to structure your data though. I'd set up a has_many :through relationship instead.

code:
rails generate model magic_five_potion magic_five_id:integer potion_id:integer position:integer

class MagicFivePotions < ActiveRecord::Base
  belongs_to :magic_five
  belongs_to :potion
  validates :position, :present => true, :inclusion => {:in => 0..4}, 
            :uniqueness => {:scope => :magic_five_id}
end

class MagicFive < ActiveRecord::Base
  has_many :magic_five_potions
  has_many :potions, :through => :magic_five_potions, :order => :position
  
  def potion_in_position(pos)
    magic_five_potions.where(:position => pos).first.potion
  end
end
This way if you ever need to make changes to the number of potions or the relationships or the rules surrounding them your code will be easier to change.

mmachine
Jan 5, 2006

prom candy posted:

With the way you've got it set up you would use something like:
code:
belongs_to :potion_1, :class_name => "Potion"
belongs_to :potion_2, :class_name => "Potion"
belongs_to :potion_3, :class_name => "Potion"
belongs_to :potion_4, :class_name => "Potion"
belongs_to :potion_5, :class_name => "Potion"
This probably isn't the best way to structure your data though. I'd set up a has_many :through relationship instead.

code:
rails generate model magic_five_potion magic_five_id:integer potion_id:integer position:integer

class MagicFivePotions < ActiveRecord::Base
  belongs_to :magic_five
  belongs_to :potion
  validates :position, :present => true, :inclusion => {:in => 0..4}, 
            :uniqueness => {:scope => :magic_five_id}
end

class MagicFive < ActiveRecord::Base
  has_many :magic_five_potions
  has_many :potions, :through => :magic_five_potions, :order => :position
  
  def potion_in_position(pos)
    magic_five_potions.where(:position => pos).first.potion
  end
end
This way if you ever need to make changes to the number of potions or the relationships or the rules surrounding them your code will be easier to change.

Very nice -- right now I went with the first solution. Second solution definitely feels like the right one, though. Actually a lot of our models for this app use mapping tables like you describe already -- I think we wrote this specific feature off as a hard five cap, so probably worth refactoring on the next pass.

Lexicon
Jul 29, 2003

I had a beer with Stephen Harper once and now I like him.
Anyone have any insight to share on how to structure view specific javascript files? I have "document.ready" code for specific views that I want to fire *only* during those view executions...

manero
Jan 30, 2006

Lexicon posted:

Anyone have any insight to share on how to structure view specific javascript files? I have "document.ready" code for specific views that I want to fire *only* during those view executions...

There are a couple approaches. One is to include a guard statement in your document.ready code to check to see if the correct elements are there (i.e. you are on the correct page for your code)

IMO a better way to do it is to break the page-specific code into a separate file, and only include that JS on the pages that need it:

app/views/layouts/application.html.erb:
code:
<!-- ... other page content here -->
  <%= yield :javascripts %>
</body>
</html>
And then in app/views/posts/index.html.erb:

code:
<%= content_for :javascripts do %>
  <%= javascript_include_tag "posts_index" %>
<% end %>
The problem is then you always have to add posts_index.js into the config.assets.precompile array in your app config, which is easy to miss, and is a PITA because it'll work in development mode and then break in production. I do like keeping things in the application.js manifest.

I tend to split the JS files between the definition of the code (e.g. a coffeescript class), and the creation/usage of it. This lets you still precompile posts_index.js from your application.js, and then do something like this on your page:

code:
<%= content_for :javascripts do %>
  $(function() {
    var myThing = new MyThing();
    myThing.doWhatever();
  });
<% end %>

Cocoa Crispies
Jul 20, 2001

Vehicular Manslaughter!

Pillbug
Use something like https://github.com/thoughtbot/flutie/blob/master/lib/flutie/page_title_helper.rb to put a controller & action class on your body tag, and guard your JS files with that.

if you're using jQuery, you can use http://api.jquery.com/jQuery/#jQuery3 instead of document.ready too.

PastaSky
Dec 15, 2009
I'm trying to run a single migrate an am running into a problem. I was wondering if anyone could help me.

code:

I do ruby script/console
I do require 'db/migrate/20130415224445_create_plan_item_updates.rb'
Then I do PlanItemUpdate.up

and the error I see is:
code:
PlanItemUpdate.up
NoMethodError: undefined method `up' for PlanItemUpdate(Table doesn't exist):Class
        from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/base.rb:1959:in `method_missing'
        from (irb):4
Edit:
uhg im an idiot. Its CreatePlanItemUpdates.up

PastaSky fucked around with this message at 02:05 on Apr 30, 2013

prom candy
Dec 16, 2005

Only I may dance

Lexicon posted:

Anyone have any insight to share on how to structure view specific javascript files? I have "document.ready" code for specific views that I want to fire *only* during those view executions...

http://viget.com/inspire/extending-paul-irishs-comprehensive-dom-ready-execution

I love this system.

Lexicon
Jul 29, 2003

I had a beer with Stephen Harper once and now I like him.

manero posted:

js stuff

Thanks Manero, Cocoa Crispies, PastaSky, prom candy; that should be enough of a lead to get me started.

Sub Par
Jul 18, 2001


Dinosaur Gum
My app has a "feed" of sorts where a user logs in and a bunch of stuff is displayed similar to a Facebook feed. Each item on the feed has a static URL associated with it, and that URL is obviously available in the view. I would like a user to be able to bookmark that static URL by clicking a link. I have a bookmark model that belongs_to user and a user model that has_many bookmarks. But I can't wrap my head around how to make a single URL that the user can click that will create an entry in the bookmark table. Does this make sense?

Smol
Jun 1, 2011

Stat rosa pristina nomine, nomina nuda tenemus.
Either nest BookmarksController under Users in the routes file and POST to /users/foo/bookmarks (BookmarksController#create) or grab the user id from your session variable and POST to /bookmarks.

DreadCthulhu
Sep 17, 2008

What the fuck is up, Denny's?!
Question for you Rails experts: how does Rails decide what environment the code is running as? Is ruby reaching out to the shell and checking that a certain environment variable is set correctly?

On that note, do you know how the web app decides what database to talk to when it receives a call? For example, say I'm running functional tests that hit Postgres. Does every single ActiveRecord call check the environment variable? Does the test suite just reset it back to what it was before once it's done?

UxP
Aug 27, 2007

DreadCthulhu posted:

Question for you Rails experts: how does Rails decide what environment the code is running as? Is ruby reaching out to the shell and checking that a certain environment variable is set correctly?

On that note, do you know how the web app decides what database to talk to when it receives a call? For example, say I'm running functional tests that hit Postgres. Does every single ActiveRecord call check the environment variable? Does the test suite just reset it back to what it was before once it's done?

Kind of, yeah: https://github.com/rails/rails/blob/master/railties/lib/rails.rb#L56

ActiveRecord memoizes the environment so it won't actually call out to find the environment on every request. Ruby itself will populate the ENV hash with your shell's environment variables. Start up an irb session and call that magic object, it should be identical to calling env from bash or zsh or whatever.

manero
Jan 30, 2006

DreadCthulhu posted:

On that note, do you know how the web app decides what database to talk to when it receives a call? For example, say I'm running functional tests that hit Postgres. Does every single ActiveRecord call check the environment variable? Does the test suite just reset it back to what it was before once it's done?

To be a bit more specific, ActiveRecord establishes connections when the Rails environment starts, so usually once per test run, if that makes sense. It simply connects to the environment specified in RAILS_ENV, as specified in your database.yml, which then is reflected as Rails.env in your running app.

DreadCthulhu
Sep 17, 2008

What the fuck is up, Denny's?!

UxP posted:

Kind of, yeah: https://github.com/rails/rails/blob/master/railties/lib/rails.rb#L56

ActiveRecord memoizes the environment so it won't actually call out to find the environment on every request. Ruby itself will populate the ENV hash with your shell's environment variables. Start up an irb session and call that magic object, it should be identical to calling env from bash or zsh or whatever.

To be a bit more specific, ActiveRecord establishes connections when the Rails environment starts, so usually once per test run, if that makes sense. It simply connects to the environment specified in RAILS_ENV, as specified in your database.yml, which then is reflected as Rails.env in your running app.

First of all, ||= is brilliant, glad you pointed that out. I don't write much Ruby these days, and so I had to immediately check if JS happened to have that operator, since I abuse the bejesus out of regular || for defaults. Too bad it doesn't, one day maybe :) It makes for quite elegant oneliners.
Also defaulting to development is a smart idea, you can fatfinger a serious trip to DB backups there.

Embarrassing. I never realized that RAILS_ENV was literally an environment variable. I thought it was some kind of magical switch for rake... Does anybody know how they manage to set the variable at the end of the command? Testing in bash only works if I do something like:

code:
FOO=helloworld ruby -e "print ENV['FOO']"
not

code:
ruby -e "print ENV['FOO']" FOO=helloworld
which seems to be how they do it. I'm surely missing something.

raej
Sep 25, 2003

"Being drunk is the worst feeling of all. Except for all those other feelings."
I'm having some headache with Devise and routes.

I'm wanting to go to a user's cellar instead of the root_path when a user signs in.

A user's cellar is located at /users/:id/cellar with the following routes:

cellar_user GET /users/:id/cellar(.:format) users#cellar

I added the following to my action_controller:
code:
def after_sign_in_path_for(resource)
 	cellar_user(resource)
  end
But I'm getting a NoMethodError:

NoMethodError at /users/sign_in
undefined method `cellar_user' for #<Devise::SessionsController:0x434a00>

What am I missing here?

manero
Jan 30, 2006

raej posted:

But I'm getting a NoMethodError:

NoMethodError at /users/sign_in
undefined method `cellar_user' for #<Devise::SessionsController:0x434a00>

What am I missing here?

cellar_user_path (or cellar_user_url)

raej
Sep 25, 2003

"Being drunk is the worst feeling of all. Except for all those other feelings."

manero posted:

cellar_user_path (or cellar_user_url)

That's getting a different error, but I feel like it's moving:

ActionController::RoutingError at /users/sign_in
No route matches {:action=>"cellar", :controller=>"users"}

My routes.rb for users looks like this:
code:
 devise_for :users
  resources :users do
    member do
      get :cellar, :following, :followers
    end
  end

Smol
Jun 1, 2011

Stat rosa pristina nomine, nomina nuda tenemus.
For anyone running nginx or recent enough Phusion Passenger, upgrade ASAP.

http://mailman.nginx.org/pipermail/nginx-announce/2013/000112.html

https://groups.google.com/forum/?fromgroups=#!topic/phusion-passenger/bbXdQReZX00

manero
Jan 30, 2006

raej posted:

That's getting a different error, but I feel like it's moving:

ActionController::RoutingError at /users/sign_in
No route matches {:action=>"cellar", :controller=>"users"}

My routes.rb for users looks like this:
code:
 devise_for :users
  resources :users do
    member do
      get :cellar, :following, :followers
    end
  end

Ah, I'd say do "rake routes" from your terminal and see how it maps out. I'm fuzzy with how it would name it with all the nesting. It might be something like "devise_user_cellar_path(current_user)" or "user_cellar_path(current_user)"

A MIRACLE
Sep 17, 2007

All right. It's Saturday night; I have no date, a two-liter bottle of Shasta and my all-Rush mix-tape... Let's rock.

manero posted:

Ah, I'd say do "rake routes" from your terminal and see how it maps out. I'm fuzzy with how it would name it with all the nesting. It might be something like "devise_user_cellar_path(current_user)" or "user_cellar_path(current_user)"

Also, if you have a lot of routes (for a very large application), it can be handy to pipe rake routes into grep and give it a search term. Like `rake routes | grep mything`. It was a huge help getting acclimated to my first big rails project.

Sewer Adventure
Aug 25, 2004

DreadCthulhu posted:

First of all, ||= is brilliant, glad you pointed that out. I don't write much Ruby these days, and so I had to immediately check if JS happened to have that operator, since I abuse the bejesus out of regular || for defaults. Too bad it doesn't, one day maybe :) It makes for quite elegant oneliners.

Check out CoffeeScript, which is enabled by default in Rails installations.

raej
Sep 25, 2003

"Being drunk is the worst feeling of all. Except for all those other feelings."

manero posted:

Ah, I'd say do "rake routes" from your terminal and see how it maps out. I'm fuzzy with how it would name it with all the nesting. It might be something like "devise_user_cellar_path(current_user)" or "user_cellar_path(current_user)"

That's the thing. I did rake routes and see this:

code:
cellar_user GET    /users/:id/cellar(.:format)    users#cellar
But even doing a link_to cellar_user on a user's page gives the same NameError:

NameError at /users/1
undefined local variable or method `cellar_user' for #<#<Class:0x5194cf8>:0x2c62ba8>

manero
Jan 30, 2006

raej posted:

That's the thing. I did rake routes and see this:

code:
cellar_user GET    /users/:id/cellar(.:format)    users#cellar
But even doing a link_to cellar_user on a user's page gives the same NameError:

NameError at /users/1
undefined local variable or method `cellar_user' for #<#<Class:0x5194cf8>:0x2c62ba8>

cellar_user_path(current_user)

You need to choose either _path (which will just be like /users/123/cellar), or _url, which will give you the host plus the path.

DreadCthulhu
Sep 17, 2008

What the fuck is up, Denny's?!
Regarding Devise, does anybody know if and how Devise persists sessions across reboots of the web app? Does it happen to store them somewhere in a db, and if so, does it cache them in memory in any way to avoid having to hit the DB on every request that couldn't be authenticated in memory? Couldn't clearly see what's going on there from the source, the thing is pretty beefy.

raej
Sep 25, 2003

"Being drunk is the worst feeling of all. Except for all those other feelings."

manero posted:

cellar_user_path(current_user)

You need to choose either _path (which will just be like /users/123/cellar), or _url, which will give you the host plus the path.

aha! It was _path that was needed. Thank you so much!

KoRMaK
Jul 31, 2012



I want to override the I18n::translate method for my whole app. Why? Because the default scaffolded views use the f.label method and that calls translate and I want translate to conform to our special locale system. Normally it pulls the labels from the en.yml file under helpers.label.model.field

I need to also have it check another location.

Smol
Jun 1, 2011

Stat rosa pristina nomine, nomina nuda tenemus.

DreadCthulhu posted:

Regarding Devise, does anybody know if and how Devise persists sessions across reboots of the web app? Does it happen to store them somewhere in a db, and if so, does it cache them in memory in any way to avoid having to hit the DB on every request that couldn't be authenticated in memory? Couldn't clearly see what's going on there from the source, the thing is pretty beefy.

Depends on your session storage strategy, i.e. it could be either cookies (default), your sql database via activerecordstore or something like memcached.

Adbot
ADBOT LOVES YOU

DreadCthulhu
Sep 17, 2008

What the fuck is up, Denny's?!

Smol posted:

Depends on your session storage strategy, i.e. it could be either cookies (default), your sql database via activerecordstore or something like memcached.

So by default the cookies are signed and basically given full trust regarding whether the user is who he claims he is? Permissions in there as well?

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply