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
prom candy
Dec 16, 2005

Only I may dance
I think it just takes some time to understand it. It's not really namespaces so much as figuring out what's been included where. If you're writing a new class in Ruby you have to realize that you're not going to have direct access to any methods unless you include the module that they're in or they're methods in the class itself (or in its parent tree).

That said, trying to use view helpers outside of views can be frustrating.

Adbot
ADBOT LOVES YOU

Thoom
Jan 12, 2004

LUIGI SMASH!

prom candy posted:

That said, trying to use view helpers outside of views can be frustrating.

It's mostly a documentation problem. Since it's not written down anywhere official, it took like an hour of googling to figure out that the named route helpers were contained in Rails.application.routes.url_helpers (a module returned by a class returned by a class returned by a... I want to say module?). Looking at the rails source wasn't any help either, because it's all hidden behind 7 layers of magic and abstraction.

Pardot
Jul 25, 2001




Try Sinatra. It does much less than rails so it's easier to understand. I use sintra and sequel for most things these days.

http://www.sinatrarb.com/
http://sequel.rubyforge.org/

Pardot fucked around with this message at 22:20 on Dec 8, 2013

Physical
Sep 26, 2007

by T. Finninho
CanCan talk: I have a class that has multiple types to it. It is all the same type though except for a field that helps tell the rest of our system how to handle it. So there is only 1 model, but several uses. As such, we want to limit 3 types of user roles to different permissions for the 3 types.

My main option is to create a model to further refine each type. However I'd like to know if I can do a test on the type without having to put stuff in each of the RESTFUL actions.

Ideally I'd like to do this:

code:
class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new #guest user
    
    if user.role? :accountowner
      can :manage, Department 
      can :manage, Plan 
        if Plan.type == TypeA     
          #do type specific stuff
        end
    else                    
      can :read, :all  
    end 
  end
end
Looking through the examples I suppose I could re-purpose this to do what I want (as outlined nicely here https://github.com/ryanb/cancan/wiki/Defining-Abilities-with-Blocks). But I have a question about the try statement as the doc is poor and refers to variables that are not defined (says method but only has parameters a and b so which is which? http://api.rubyonrails.org/classes/Object.html#method-i-try):
code:
class Ability
  include CanCan::Ability
  
  def initialize(user)
    user ||= User.new # guest user
    
    if user.role? :admin
      can :update, Comment do |comment|
        comment.try(:user) == user || user.role?(:moderator) #what is this line doing?
      end      
    end
    
  end
end

prom candy
Dec 16, 2005

Only I may dance
When you say that you have one model but several types are you talking about Single Table Inheritance? is there a class called TypeA?

The code that you reference for comments is an example of passing a block to a CanCan call in order to further refine access:

code:
if user.role? :accountowner
  can(:create, Plan)
  can([:update, :destroy], Plan) do |plan|
    plan.type == TypeA
  end
end
If the code block returns truthy the user will be granted access, if it returns falsey the user will be denied access. Here's another example based on letting a user only edit their own hockey cards (for some reason I am imagining a system that lets users catalogue their hockey cards):

code:
if user.role? :regular_user
  can(:create, HockeyCard)
  can([:update, :destroy], HockeyCard) do |hockey_card|
    hockey_card.user == user
  end
end
Makes sense?

Physical
Sep 26, 2007

by T. Finninho
I meant just this line (the try statement)
comment.try(:user) == user || user.role?(:moderator) #what is this line doing?

But I think I get what try does now, it sees if user field exists and that the object its being called on exists right?

prom candy
Dec 16, 2005

Only I may dance
http://archives.ryandaigle.com/articles/2008/11/20/what-s-new-in-edge-rails-object-try

Smol
Jun 1, 2011

Stat rosa pristina nomine, nomina nuda tenemus.
Why aren't you looking at the API documentation first? Typing 'try' to that search box would've given you the answer in 5 seconds flat.

http://api.rubyonrails.org/

Physical
Sep 26, 2007

by T. Finninho

Smol posted:

Why aren't you looking at the API documentation first? Typing 'try' to that search box would've given you the answer in 5 seconds flat.

http://api.rubyonrails.org/
If you read what I said, and what the doc says, you will see that I was actually referring to the doc library you just linked. The api.rubyonrails.org docs is skimpy in some places.

I now have it as one of my homepage tabs though.

prom candy
Dec 16, 2005

Only I may dance
Does anyone (like pardot) know how to set BUNDLE_WITHOUT on the Cedar stack on Heroku? It doesn't seem to do anything when I follow Heroku's directions.

Big Nubbins
Jun 1, 2004
Apparently I haven't made the effort to understand the semantics of nested vs. scoped resources enough to know whether I'm structuring my routes and controllers wrong. I'm sure it's incredibly basic, but I made some assumptions early on that made things kind of messy. When you have an association like "a blog post has many comments", it's obvious that you'd use a nested resource since comments are always accessed in the context of a post. With the case of something like "a department has many employees", the department context is optional.

I wanted to have "pretty" urls, so at the time I felt I needed 2 controllers: one that's unscoped and one that's always scoped to a department. Obviously you could combine them in one controller, but I didn't want to do something like:
code:
# routes.rb
resources :departments do
    resources :employees
end

# employees_controller.rb
def index
    if params.has_key(:department_id)
        @employees = Employee.find_by_department params[:department_id]
    else
        @employees = Employee.all
end
I don't hate myself that much, and I didn't want to always have scoping bullshit like "department=1" hanging around in the query string. What I ended up with was something like:
code:
# routes.rb
resources :employees
scope 'department' do
    resources :employees
end

# employees_controller.rb
def index
    @employees = Employee.all
end

# department/employees_controller.rb
def index
    @employees = Employee.joins{ department }
        .where{ department.id == (params[:department_id]) } # I love Squeel blocks
end
and the URLs would be something like /employees and /accounting/employees.

This is just a simple example, but the dataset I'm working with is necessarily highly relational and there are much more complex relationships than this. After some time, I started drowning in specialized controllers whose only real difference was in what table(s) they're performing a join to (or not). So where's the middle ground between flexible, "pretty" routing with lots of specialized controllers and a single, swiss-army-controller that handles all your scoping and filtering needs?

Writing this post makes me feel like I'm really bad at Rails.


Thoom posted:

Disregarding my brain fart about scoping rules, I still think it's dumb how poorly documented the scoping of various namespaces is in Rails.
http://www.ruby-doc.org/docs/ (home of the official core API docs as far as I'm aware) reference many guides with detailed info on lexical scoping.

Big Nubbins fucked around with this message at 23:30 on Apr 5, 2012

Thoom
Jan 12, 2004

LUIGI SMASH!

greasy digits posted:

http://www.ruby-doc.org/docs/ (home of the official core API docs as far as I'm aware) reference many guides with detailed info on lexical scoping.

I wasn't talking about Ruby's scoping rules. I was talking about incredibly obscure Rails implementation details like Rails.application.routes.url_helpers that are sometimes useful to have outside the context Rails provides them in by default.

Pardot
Jul 25, 2001




prom candy posted:

Does anyone (like pardot) know how to set BUNDLE_WITHOUT on the Cedar stack on Heroku? It doesn't seem to do anything when I follow Heroku's directions.

By default the slug compiler does not see your runtime environment, so it doesn't know you have that You need to set the user_env_compile flag on your app. You can do that with the newish heroku labs feature https://devcenter.heroku.com/articles/labs-user-env-compile

In general we don't like user_env_compile. Your build environment should be different than your run environment, so don't expect this lab feature to stick around forever. Your running app doesn't care about BUNDLE_WITHOUT, and your slug compiler doesn't give a gently caress about your DATABASE_URL. Until that mess is all figured out, user_env_compile is the answer.

prom candy
Dec 16, 2005

Only I may dance

Pardot posted:

By default the slug compiler does not see your runtime environment, so it doesn't know you have that You need to set the user_env_compile flag on your app. You can do that with the newish heroku labs feature https://devcenter.heroku.com/articles/labs-user-env-compile

In general we don't like user_env_compile. Your build environment should be different than your run environment, so don't expect this lab feature to stick around forever. Your running app doesn't care about BUNDLE_WITHOUT, and your slug compiler doesn't give a gently caress about your DATABASE_URL. Until that mess is all figured out, user_env_compile is the answer.

Awesome, thanks. If you think of it, do you mind updating this thread when you guys have a different solution for this or if this option is going to be removed? Somehow I always manage to miss stuff like that.

Big Nubbins
Jun 1, 2004
I think I found the "middle ground" I was seeking earlier in the form of the has_scope gem. Still, I'd like to know what "The Rails Way" is to keep that poo poo DRY.

Speaking of scopes, is there a gem that evals your models to provide basic sorting, filtering, and association scopes? Hobo's Scopes module is pretty much right on the money, but without the reliance on method_missing to work the magic for you. The API I'm putting together is pretty heavy on the sorting and filtering, and it's getting to the point where the majority of my model class definition consists of scope definitions.

Cocoa Crispies
Jul 20, 2001

Vehicular Manslaughter!

Pillbug

greasy digits posted:

I think I found the "middle ground" I was seeking earlier in the form of the has_scope gem. Still, I'd like to know what "The Rails Way" is to keep that poo poo DRY.

I tend to move the finder into a controller method:
code:
class EmployeesController
  helper_method :employee, :employees

  def index
  end

  def show
  end

  def employee
    return Employee.find params[:id] unless department
    return department.employees.find params[:id]
  end

  def employees
    return Employee.all unless department
    return department.employees.all
  end

  def department
    return nil unless params[:department_id]
    return Department.find params[:department_id]
  end
end

manero
Jan 30, 2006

BonzoESC posted:

I tend to move the finder into a controller method:

decent_exposure does this (and more) for you, and it's full of awesome.

manero fucked around with this message at 04:33 on Apr 6, 2012

k-selectride
May 24, 2004
belgian waffle
I'm trying to come up with a simple ranking system for a Post model in order to display them on the front page my website by descending rank. But I also want some sort of time decay on the rank so certain posts don't stay on the front page forever. The solution i'm trying to implement is to schedule a recurring cron job with the 'whenever' gem that takes the current rank and multiplies it by a factor of Math.exp(-time_since_creation/tau) where tau is the half-life, so to speak.

So my schedule.rb for whenever would be something like

code:
every 1.day, :at => '3:00 am' do
   runner "Post.update_rank"
end
My question is how to craft the update_rank method? I don't think it's possible to do that kind of thing with just a single SQL query. Is there a way to avoid loading every Post instance into memory and updating them individually? Alternatively, I would be open to another method for time-decaying of rank.

I'm pretty new to Rails, i've only recently completed railstutorial.org.

prom candy
Dec 16, 2005

Only I may dance
I'm not really an SQL wizard but couldn't you potentially write an SQL query that handles the sorting? Something like "ORDER BY (EXP(-time_since_creation/tau)" basically? I'm not sure how performance on that would be though.

Alternately you might be able to run an update_all method to save that value to the posts themselves.

code:
Post.update_all :true_rank => "EXP(-time_since_creation/tau)"
I think it's largely going to depend on your database and how many posts you're looking at keeping in the system but having the database handle the math might be the best thing to do. Otherwise you're going to have to loop through all of your posts, I don't think you can put Ruby logic in an update_all statement. I'm interested to see how other people might approach this.

k-selectride
May 24, 2004
belgian waffle
Well the thing is that time_since_creation isn't an attribute in the Model, I have a :created_at attribute and time_since_creation = (Time.now - post.created_at) or something like that. My activerecord knowledge is pretty basic, I don't know if it's possible to write a statement that would incorporate that.

prom candy
Dec 16, 2005

Only I may dance
You would probably have to do that operation at the database level as well. Assuming we're looking at millions of post objects I'm not certain if there's going to be a way that runs nightly updates on all of them that isn't a super expensive operation. Moving it to the order statement and caching aggressively is probably going to be your best bet, but others may have a better solution. This might be a good question for the SQL thread as well.

Oh My Science
Dec 29, 2008
When using postgresql in a new app it won't allow me to connect unless I specify a host:

code:
database.yml

development:
  adapter: postgresql
  encoding: unicode
  database: ***
  pool: 5
  host: localhost  <--
  username: ***
  password: ***
Using my previous setup I never had to include that option, what happened?


Edit: It was a pathing issue. Once I corrected the path in .bash_profile and reinstalled the pg gem it is working as expected again.

What's really bothering me is the inability to play with Rails Apps Composer, since the active record recipe doesn't allow me to provide the username / password / host options. It simply tries using the default rails database.yml, which results in the script being unable to access the db.

While I'm at it, how do people feel about Rails Apps Composer, or Rails Wizard? Are they a good idea to use for basic app templates? Or would you rather stick to the manual approach of setting up a new app?

Oh My Science fucked around with this message at 19:02 on Apr 9, 2012

Cocoa Crispies
Jul 20, 2001

Vehicular Manslaughter!

Pillbug

Oh My Science posted:

While I'm at it, how do people feel about Rails Apps Composer, or Rails Wizard? Are they a good idea to use for basic app templates? Or would you rather stick to the manual approach of setting up a new app?
I don't feel like I make enough new apps to get anything out of those. The manual approach means you're not tied in to what those tools support.

prom candy
Dec 16, 2005

Only I may dance
I use Rails Wizard all the time.

Sivart13
May 18, 2003
I have neglected to come up with a clever title

k-selectride posted:

My question is how to craft the update_rank method? I don't think it's possible to do that kind of thing with just a single SQL query. Is there a way to avoid loading every Post instance into memory and updating them individually? Alternatively, I would be open to another method for time-decaying of rank.

I might be wrong, but I feel like this hand-baked SQL would be pretty close (I have not tested it on anything)

code:
ActiveRecord::Base.connection.execute(<<-SQL
  UPDATE posts
  SET rank = rank * exp(-1 * ( (#{Time.now} - created_at) / #{tau} ) )
SQL
)
(you may have to do some other little dance to ensure Time.now and created_at are in compatible units so that subtraction and division would actually work)

... in PostgreSQL, anyway, which has a native 'exp' function. I don't know a lot about sqlite.

Sivart13 fucked around with this message at 19:28 on Apr 9, 2012

k-selectride
May 24, 2004
belgian waffle

Sivart13 posted:

I might be wrong, but I feel like this hand-baked SQL would be pretty close (I have not tested it on anything)

code:
ActiveRecord::Base.connection.execute(<<-SQL
  UPDATE posts
  SET rank = rank * exp(-1 * ( (#{Time.now} - created_at) / #{tau} ) )
SQL
)
(you may have to do some other little dance to ensure Time.now and created_at are in compatible units so that subtraction and division would actually work)

... in PostgreSQL, anyway, which has a native 'exp' function. I don't know a lot about sqlite.

Thanks for the help everybody, I'll give this a shot and see how it works. If it gets too complicated I'll simply implement time based weight that gets added to votes. So I'll pick an arbitrary reference day, say 01/01/12 and calculate the change in rank from a vote as post.rank = post.days_since_ref_date * weight + 1. Where weight is an integer between 1-10 to determine how quickly I want new posts to overtake older ones.

Or something like that.

prom candy
Dec 16, 2005

Only I may dance
Your solution really should depend on how many posts you have in the database. Running a once-a-day update_all on a few hundred posts isn't a big deal, but that solution won't really scale.

Pardot
Jul 25, 2001




While the half life thing is kinda neat, does it really give you any more than select * from posts where created_at > '5 days ago'::interval order by created_at desc limit 20 ? That one is super easy, seems like it gives you roughly the same things, and you just need to make sure you have an index on created_at.

prom candy
Dec 16, 2005

Only I may dance
I think the issue is that he wants to combine their age with a rank that's determined through other means (user votes maybe?)

That was my take anyway.

prom candy
Dec 16, 2005

Only I may dance
Not strictly a Rails question but is there any way to improve the spin-up time on free Heroku apps? Or to profile the spin-up and determine why it's slow?

Cocoa Crispies
Jul 20, 2001

Vehicular Manslaughter!

Pillbug

prom candy posted:

Not strictly a Rails question but is there any way to improve the spin-up time on free Heroku apps? Or to profile the spin-up and determine why it's slow?

It's probably the same reason it's slow to spin up on your machine, if you want to profile it locally.

Pardot
Jul 25, 2001




BonzoESC posted:

It's probably the same reason it's slow to spin up on your machine, if you want to profile it locally.

This + how big your slug is, since it has to be downloaded first.

prom candy
Dec 16, 2005

Only I may dance
Downloaded from where to where? Is there a size that I should try to stay under?

I saw on Stack Overflow that installing addons like New Relic will keep your application alive because they hit it fairly frequently. Is this considered abuse/misuse of the free service provided by Heroku?

Cocoa Crispies
Jul 20, 2001

Vehicular Manslaughter!

Pillbug

prom candy posted:

Downloaded from where to where? Is there a size that I should try to stay under?

Presumably from S3 to EC2.

https://devcenter.heroku.com/articles/slug-size says 100mb is a hard limit, 25mb is good. Obviously, 1mb would own, but good luck.

Pardot
Jul 25, 2001




BonzoESC posted:

Presumably from S3 to EC2.

https://devcenter.heroku.com/articles/slug-size says 100mb is a hard limit, 25mb is good. Obviously, 1mb would own, but good luck.

This. While the download speeds are extremely fast, it is still a limiting factor.

prom candy posted:

I saw on Stack Overflow that installing addons like New Relic will keep your application alive because they hit it fairly frequently. Is this considered abuse/misuse of the free service provided by Heroku?

It is considered abuse, but more importantly it makes me sad. People who do this make it harder for us to offer a free service, and I like it that we have a free service.

Jam2
Jan 15, 2008

With Energy For Mayhem
I'm learning metaprogramming in Ruby for a class project. One of the assigned tasks is to write a method which allows me to create a new method at runtime. I'm using class_eval to accomplish this.

I'm at the point where I'm defining the new method using class_eval and I'd like to store a number literal inside the new method definition. Is there a way to dereference a variable so it gets stored as a literial?

enki42
Jun 11, 2001
#ATMLIVESMATTER

Put this Nazi-lover on ignore immediately!
Related question to Heroku spinning down - how does this work on the Cedar stack? If I have 1 web dyno and 1 worker dyno, is it possible for that web dyno to spin down (i.e. do I need to have at least 2?)

prom candy
Dec 16, 2005

Only I may dance

Jam2 posted:

I'm learning metaprogramming in Ruby for a class project. One of the assigned tasks is to write a method which allows me to create a new method at runtime. I'm using class_eval to accomplish this.

I'm at the point where I'm defining the new method using class_eval and I'd like to store a number literal inside the new method definition. Is there a way to dereference a variable so it gets stored as a literial?

Would define_method work for what you're doing?

Oh My Science
Dec 29, 2008

enki42 posted:

Related question to Heroku spinning down - how does this work on the Cedar stack? If I have 1 web dyno and 1 worker dyno, is it possible for that web dyno to spin down (i.e. do I need to have at least 2?)

I am fairly certain it does not count workers towards spin down, and that yes, at least two dinos are needed.

Adbot
ADBOT LOVES YOU

Pardot
Jul 25, 2001




Oh My Science posted:

I am fairly certain it does not count workers towards spin down, and that yes, at least two dinos are needed.

You're correct. I forgot that that was the case. I'm personally trying to get this changed, of course no promises that it will happen or any eta, but I think it's bad.

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