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
KoRMaK
Jul 31, 2012



How do I get the setings or params of a chain while I am in that chain? for example

Ruby code:
class User

  self.my_function
    #this function will be chained with other methods
    #I want to be able to pull the sql variables that preceed it
  end
end

current_account.users.my_function #current_account is an account object with a has_many to users
How do I find out the params that are settting up the chain inside of my_function?

Adbot
ADBOT LOVES YOU

MasterSlowPoke
Oct 9, 2005

Our courage will pull us through
Ruby code:
class ChainClass
  def initialize(hello = 'world')
    @hello = hello
    @counter = 0
  end

  def chain
    @counter += 1
    self
  end

  def puts_chain
    puts "#{@hello}, #{@counter}"
    self
  end
end

chain1 = ChainClass.new
chain1.chain.chain.puts_chain # => world, 2
chain2 = ChainClass.new("hi goon")
chain2.chain.chain.chain.chain.puts_chain.chain # => hi goon, 4

KoRMaK
Jul 31, 2012



MasterSlowPoke posted:

Ruby code:
class ChainClass
  def initialize(hello = 'world')
    @hello = hello
    @counter = 0
  end

  def chain
    @counter += 1
    self
  end

  def puts_chain
    puts "#{@hello}, #{@counter}"
    self
  end
end

chain1 = ChainClass.new
chain1.chain.chain.puts_chain # => world, 2
chain2 = ChainClass.new("hi goon")
chain2.chain.chain.chain.chain.puts_chain.chain # => hi goon, 4
Thanks, but I'm not sure this will apply to my situation. Doing current_account.users builds a query that is "select * from users where account_id = 1" (1 being the id of current_account).

So I want to do current_account.users.my_function and inside of my function I'd like to pluck out the account_id being used. I'd also like to just in general know if there is some meta properties I can inspect to get all the variables currently being passed in to the query maker.

fantastic in plastic
Jun 15, 2007

The Socialist Workers Party's newspaper proved to be a tough sell to downtown businessmen.

KoRMaK posted:

Thanks, but I'm not sure this will apply to my situation. Doing current_account.users builds a query that is "select * from users where account_id = 1" (1 being the id of current_account).

So I want to do current_account.users.my_function and inside of my function I'd like to pluck out the account_id being used. I'd also like to just in general know if there is some meta properties I can inspect to get all the variables currently being passed in to the query maker.

I'm not sure I understand the question.

Ruby code:
current_account.id
should return the id of current_account, assuming that current_account is set. This should match the account_id in the related users, which I think is what you're asking for?

Ruby code:
current_account.users.first.account_id
should return the account_id of the first user in the response from current_account, assuming it's set somewhere. Since it's a has_many and I assume account_id is the key that sets up the associations, they should all be the same.

MasterSlowPoke
Oct 9, 2005

Our courage will pull us through
At the place I'm working all the view partials are put into concern folders, (like app/views/model_name/concerns/_partials.html.erb). Is this common?

KoRMaK
Jul 31, 2012



MasterSlowPoke posted:

At the place I'm working all the view partials are put into concern folders, (like app/views/model_name/concerns/_partials.html.erb). Is this common?
Is concern another name for interface? I can't answer your question, but I noticed "concerns" in the rails lexicon recently and it reminded me of interfaces in like C# or C++

kayakyakr
Feb 16, 2004

Kayak is true

MasterSlowPoke posted:

At the place I'm working all the view partials are put into concern folders, (like app/views/model_name/concerns/_partials.html.erb). Is this common?

No, that's not the right place for them. Partials either live in a views/common or views/model_name depending on their use case.

KoRMaK posted:

Is concern another name for interface? I can't answer your question, but I noticed "concerns" in the rails lexicon recently and it reminded me of interfaces in like C# or C++

Concern is a fairly new, easy way to extend ActiveModel objects. It's a slightly cleaner method than the normal ruby include methodology.

necrotic
Aug 2, 2005
I owe my brother big time for this!

kayakyakr posted:

Concern is a fairly new, easy way to extend ActiveModel objects. It's a slightly cleaner method than the normal ruby include methodology.

It's actually for anything really. There's app/concerns, app/models/concerns, and app/controllers/concerns. Its for functionality that is reusable across multiple objects (usually of a common type, like a model or controller) but not every object. Its kind of a band-aid around fat controllers and models in my opinion. Once you include them you still end up with a fat controller or model, its just hidden away in another module.

xtal
Jan 9, 2011

by Fluffdaddy

necrotic posted:

It's actually for anything really. There's app/concerns, app/models/concerns, and app/controllers/concerns. Its for functionality that is reusable across multiple objects (usually of a common type, like a model or controller) but not every object. Its kind of a band-aid around fat controllers and models in my opinion. Once you include them you still end up with a fat controller or model, its just hidden away in another module.

Concerns increase modularity and composability, and that leads to better controllers and models and such. It doesn't prevent (or relate to) the problem of making objects that do too much.

Whenever you're adding code to a controller or model, do your best to generalize it and move it to a concern, even if it will only be used by that controller (at first.)

necrotic
Aug 2, 2005
I owe my brother big time for this!

xtal posted:

Concerns increase modularity and composability, and that leads to better controllers and models and such. It doesn't prevent (or relate to) the problem of making objects that do too much.

Whenever you're adding code to a controller or model, do your best to generalize it and move it to a concern, even if it will only be used by that controller (at first.)

My point is that when you include them the controller/model is still fat, its just hidden. It also adds a pain point in figuring out "okay so Butt.new.make_a_fart works, but where is it defined? lets go see Butt! poo poo, its not there. Okay, which of these 10 modules is it in?". Yes, you can grep 'def make_a_fart', but its taken you more steps to end up finding where its defined than it ever should have. It also has a problem with method name collisions, which are (surprise) silent in Ruby and just take the most recent as truth.

Hope you didn't accidentally override some rarely used but important method in your new module! (Yes, tests, because those always exist in the project you got hired to work on)

DONT THREAD ON ME
Oct 1, 2002

by Nyc_Tattoo
Floss Finder
I just skip straight to searching for def method. Of course that only works most of the time, thanks to metaprogramming magic.

Thalagyrt
Aug 10, 2006

necrotic posted:

My point is that when you include them the controller/model is still fat, its just hidden. It also adds a pain point in figuring out "okay so Butt.new.make_a_fart works, but where is it defined? lets go see Butt! poo poo, its not there. Okay, which of these 10 modules is it in?". Yes, you can grep 'def make_a_fart', but its taken you more steps to end up finding where its defined than it ever should have. It also has a problem with method name collisions, which are (surprise) silent in Ruby and just take the most recent as truth.

Hope you didn't accidentally override some rarely used but important method in your new module! (Yes, tests, because those always exist in the project you got hired to work on)

Last month I was working on building an APN abstraction before having my coffee and thought "send would be a great method name to use for the method that sends an APN!" Whoops.

necrotic
Aug 2, 2005
I owe my brother big time for this!

Thalagyrt posted:

Last month I was working on building an APN abstraction before having my coffee and thought "send would be a great method name to use for the method that sends an APN!" Whoops.

I think this is why you're supposed to use __send for message passing since 1.9, but basically nobody does -_-

MALE SHOEGAZE posted:

I just skip straight to searching for def method. Of course that only works most of the time, thanks to metaprogramming magic.

Yeah, me too. But it's a context switch I would much rather not be necessary.

kayakyakr
Feb 16, 2004

Kayak is true

xtal posted:

Concerns increase modularity and composability, and that leads to better controllers and models and such. It doesn't prevent (or relate to) the problem of making objects that do too much.

Whenever you're adding code to a controller or model, do your best to generalize it and move it to a concern, even if it will only be used by that controller (at first.)

Right, I blame travel head for thinking it was from ActiveModel and not ActiveSupport as it is.

But I disagree about generalizing things and moving them to concerns if they're only going to be used once. I say wait to generalize until you're about to reuse something.

Then again, I also disagree with the idea that code in controllers is something that should be avoided at any cost. I think that's dangerous thinking. I don't like obese controllers, but a controller that maintains a nice healthy weight is more beautiful than a controller that is too skinny.

xenilk
Apr 17, 2004

ERRYDAY I BE SPLIT-TONING! Honestly, its the only skill I got other than shooting the back of women and calling it "Editorial".

MrDoDo posted:

If you want to learn how to be a better ruby programmer I would suggest the books Eloquent Ruby (haven't read it yet but hear great things)

Just to let you know that I got the book a few days ago and I can tell you that I enjoy it quite a bit (I'm already at chapter 5). I'm also starting to work on a pet project, using Git and TDD. Thank you! :)

MrDoDo
Jun 27, 2004

You better remember quick before we haul your sweet ass down to the precinct.

xenilk posted:

Just to let you know that I got the book a few days ago and I can tell you that I enjoy it quite a bit (I'm already at chapter 5). I'm also starting to work on a pet project, using Git and TDD. Thank you! :)

Awesome, glad to hear. Getting hands on TDD is a low pressure environment is the best thing you can do.

Also there was talk earlier about RSpec vs Test Unit. Starting with Rails 4 the testing framework inherits from Minitest which has a spec style. RSpec can definitely be pretty verbose in my opinion so this gives a pretty decent alternative

Pollyanna
Mar 5, 2005

Milk's on them.


Speaking of RSpec, I'm having a weird issue with before and let. I have this spec:

Ruby code:
require 'rails_helper'

RSpec.describe "Cuisines", :type => :request do

  let(:json) do
    JSON.parse(response.body)
  end

  before(:all) do
    @cuisines = FactoryGirl.create_list(:cuisine, 5)
  end

  describe "GET /cuisines" do

    # INDEX

    it "shows all available cuisines" do
      get cuisines_path
      expect(json.length).to eq @cuisines.length
    end
  end

  describe "GET /cuisines/:id" do

    # READ

    cuisine = @cuisines.first

    it "displays information for a cuisine" do
      get cuisine_path(cuisine.id)
      expect(json["id"]).to eq cuisine.id
    end
  end

  describe "POST /cuisines/" do

    # CREATE

    cuisine = FactoryGirl.attributes_for(:cuisine)

    it "creates a new cuisine" do
      post cuisines_path, cuisine: cuisine
      expect(json).to eq cuisine.attributes
    end
  end

end
...but it gives me this error:

code:
[...]/spec/requests/cuisines_spec.rb:36:in `block (2 levels) in <top (required)>': undefined method `first' for nil:NilClass (NoMethodError)
It seems as though @cuisines isn't actually being created, or at least I can't access it outside of the before block. Same for let(:json). However, I don't see anything wrong with the code - can someone explain to me why this wouldn't work?

Pardot
Jul 25, 2001




Pollyanna posted:


It seems as though @cuisines isn't actually being created, or at least I can't access it outside of the before block. Same for let(:json). However, I don't see anything wrong with the code - can someone explain to me why this wouldn't work?

code:
  describe "GET /cuisines/:id" do

    # READ

    cuisine = @cuisines.first # this is outside if the it block

    it "displays information for a cuisine" do
      get cuisine_path(cuisine.id)
      expect(json["id"]).to eq cuisine.id
    end
  end

Pollyanna
Mar 5, 2005

Milk's on them.


I could have sworn it was okay to do that. Goddamn, am I confused. Either way, it works now :downs: Thanks!

good jovi
Dec 11, 2000

'm pro-dickgirl, and I VOTE!

Also, don't create database objects in before(:all) blocks. They are executed outside of the transaction, so those rows won't get cleaned up.

Pollyanna
Mar 5, 2005

Milk's on them.


good jovi posted:

Also, don't create database objects in before(:all) blocks. They are executed outside of the transaction, so those rows won't get cleaned up.

I caught that a little while ago, but didn't change it for some reason. Fixed!

Chilled Milk
Jun 22, 2003

No one here is alone,
satellites in every home

good jovi posted:

Also, don't create database objects in before(:all) blocks. They are executed outside of the transaction, so those rows won't get cleaned up.

Good to know, I've probably made this mistake on some of my earlier work

Cocoa Crispies
Jul 20, 2001

Vehicular Manslaughter!

Pillbug

good jovi posted:

Also, don't create database objects in before(:all) blocks. They are executed outside of the transaction, so those rows won't get cleaned up.

That's what let is for.

kayakyakr
Feb 16, 2004

Kayak is true

Cocoa Crispies posted:

That's what let is for.

or let! if it must be created before you access the variable.

necrotic
Aug 2, 2005
I owe my brother big time for this!
Basically:

  • let(:foo) for anything to be referenced in an it or before that can be lazily created. If you see yourself using instance variables, think about using let instead.
  • The let! version is useful for things like controller and route tests so you don't have to reference foo just to create it before requesting your action. If you see yourself doing foo; get(:action), look at let!.
  • before blocks are for performing some setup repeatedly before a group of its. If the examples you are testing have no side effects, look at using before(:all) so the setup only runs once for every example; otherwise you will need to use :each (the default) to set your state before every example.
  • after blocks only really become useful in situations where you use before(:all) (and should then be after(:all)) for some form of teardown (although usually transactions take care of this).

Another nice thing about lets is composing your test data. A simple example would be a Ticket that moves through several states from new to resolved, with each state changing the behavior of the record slightly:

code:
describe Ticket do
  subject { create(:ticket, state: state) }

  context 'when the ticket is new' do
    let(:state) { 'new' }

    it 'cannot transition to resolved' do
      expect { subject.resolve! }.to raise_error(TransitionError)
    end
  end
  context 'when the ticket is acknowledged' do
    let(:state) { 'acknowledged' }

    it 'can transition to resolved' do
      expect { subject.resolved! }.not_to raise_error(TransitionError)
    end
  end
  context 'when the ticket is resolved' do
    let(:state) { 'resolved' }

    it { should be_frozen }
  end
end

Lexicon
Jul 29, 2003

I had a beer with Stephen Harper once and now I like him.
How do people feel about Elastic Beanstalk as a way to deploy Rails applications? I realize Digital Ocean or Heroku is probably a bit easier, but I'd quite like to beef up my knowledge of the AWS ecosystem. Is EB (i.e. orchestrated EC2 + RDS) a good choice?

kayakyakr
Feb 16, 2004

Kayak is true

Lexicon posted:

How do people feel about Elastic Beanstalk as a way to deploy Rails applications? I realize Digital Ocean or Heroku is probably a bit easier, but I'd quite like to beef up my knowledge of the AWS ecosystem. Is EB (i.e. orchestrated EC2 + RDS) a good choice?

Have used it. It was ok. Had to do a decent bit of configuration which was a pain. Didn't like giving up as much control as I did. After a bit, dropped it for dokku and then dropped that for capistrano + DO.

Gmaz
Apr 3, 2011

New DLC for Aoe2 is out: Dynasties of India
Does anyone have experience with subdomains in rails?

Basically I have a couple of routes that use the subdomain: /.+/ constraint on the site, the subdomains are only used for a small part of the site.

So when the user visits foo.mysite.com the problem is that all the links (e.g. navbar and footer) now link to urls with the subdomain, for instance instead of mysite.com/contact it will be foo.mysite.com/contact.

I know I can change the links from relative to absolute path (e.g. my_path_url(subdomain: false) ), but doing that for all the links in my application seems like a bad idea. Is there some way to configure rails to not link to subdomains unless it is explicitly stated or perhaps some other solution?

KoRMaK
Jul 31, 2012



Gmaz posted:

Does anyone have experience with subdomains in rails?

Basically I have a couple of routes that use the subdomain: /.+/ constraint on the site, the subdomains are only used for a small part of the site.

So when the user visits foo.mysite.com the problem is that all the links (e.g. navbar and footer) now link to urls with the subdomain, for instance instead of mysite.com/contact it will be foo.mysite.com/contact.

I know I can change the links from relative to absolute path (e.g. my_path_url(subdomain: false) ), but doing that for all the links in my application seems like a bad idea. Is there some way to configure rails to not link to subdomains unless it is explicitly stated or perhaps some other solution?
In your application controller, setup a before_filter or helper that is basically "current_account" or "current_subdomain" and look up the record based on domain info.

Gmaz
Apr 3, 2011

New DLC for Aoe2 is out: Dynasties of India
Maybe I'm not getting something but I don't understand how this will help me with linking.

Currently my navbar has something like -- link_to contacts_path, and I always want it to link to mysite.com/contacts. However if the user is on foo.mysite.com that link will go to foo.mysite.com/contacts.

I don't need subdomains for most of the site (just on one controller), the parts where I need them record lookup is already done via subdomains.

necrotic
Aug 2, 2005
I owe my brother big time for this!

Gmaz posted:

Maybe I'm not getting something but I don't understand how this will help me with linking.

Currently my navbar has something like -- link_to contacts_path, and I always want it to link to mysite.com/contacts. However if the user is on foo.mysite.com that link will go to foo.mysite.com/contacts.

I don't need subdomains for most of the site (just on one controller), the parts where I need them record lookup is already done via subdomains.

I see two options:

  • Add a main_link_to helper (or some such name) that always passes subdomain: false as an option
  • Setup a new link_to using alias_method_chain and default the subdomain option to false (but still allow it to be specified at call time)

The first option is more explicit, but requires you to use a new method for nearly all of your links. The second would be more "transparent", but could catch a new developer by surprise.

hmm yes
Dec 2, 2000
College Slice
We launched a website for our gems that we use in-house for our Rails consulting apps. You can view the site at: http://gems.agilstyle.com. These gems are all used in production Heroku apps. The current gem list is:

  • effective_addresses - Extend any ActiveRecord object to have one or more named addresses, ex. @user.billing_address
  • effective_assets - Upload images and files directly to AWS S3 with a custom form input then seamlessly organize and attach them to any ActiveRecord object
  • effective_datatables - Sort, search, export, and paginate tables of any ActiveRecord or array collection using jQuery DataTables
  • effective_logging - Automatically log all sent emails, user logins, and page views. This also will log custom events from Ruby and JavaScript
  • effective_obfuscation - Mask primary keys in a param or view
  • effective_orders - Quickly build an online store with carts, orders, automatic email receipts, and payment collection via Stripe, StripeConnect, PayPal, or Moneris
  • effective_regions - Create editable content regions within your existing, ordinary ActionView::Base views, and update content with an actually-good full-screen WYSIWYG editor
  • effective_roles - Assign multiple roles to any User or other ActiveRecord object. Select only the appropriate objects based on intelligent, chainable ActiveRecord::Relation finder methods
  • effective_style_guide - Creates a /styleguide page that renders the correct HTML for all Bootstrap3 (v3.2.0) components. Ensure that your custom CSS theme looks good with all Twitter Bootstrap3 html components

Would love feedback on the gem site (does it explain things well enough? what's missing?), the READMEs (writing docs is hard), the code (everyone has opinions), or anything else you would like to say. A lot of the work is written by our lead developer so the contributor count is low. Normally that scares us off from using another gem (we only use ones with 10+ contributors as a rule) but please don't let that scare you off in giving some feedback!

This is our first try at open source and we're really excited (and terrified) to see if what we release can provide value to other developers.

hmm yes fucked around with this message at 04:57 on Dec 11, 2014

Chilled Milk
Jun 22, 2003

No one here is alone,
satellites in every home
Well I'm definitely interested in the assets gem. Especially since it purports to play nice with ActiveAdmin. I'm on my phone so I can't really dig into it but I'll check it out soon

Cock Democracy
Jan 1, 2003

Now that is the finest piece of chilean sea bass I have ever smelled
The site is down for me but I'd be interested in checking it out. (And yeah I removed the accidental period from the end of the link.)

hmm yes
Dec 2, 2000
College Slice
Site is hosted on GitHub pages, and status says some sites are down, so just try later I guess :)

Lexicon
Jul 29, 2003

I had a beer with Stephen Harper once and now I like him.
I'm trying to learn to use rubber - I like it so far, but it seems to get stuck at various points. I'm doing the simplest of test apps right now, and it's been sitting here for quite some time (~ 30 mins):

code:
   servers: ["production.blag.com"]
    [production.blag.com] executing command
    command finished in 155ms
  * 2014-12-11 11:17:49 executing `deploy:finalize_update'
    triggering before callbacks for `deploy:finalize_update'
  * 2014-12-11 11:17:49 executing `bundle:install'
  * executing "cd /mnt/blag-production/releases/20141211191748 && bundle install --gemfile /mnt/blag-production/releases/20141211191748/Gemfile 
--path /mnt/blag-production/shared/bundle --deployment --quiet --without development test staging"
    servers: ["production.blag.com"]
    [production.blag.com] executing command
It's not clear it will be able to progress further. Anyone have any suggestions? I'm really trying to find a go-to method for deploying basic rails apps that doesn't rely on manually provisioning EC2 instances, and so far this and EB aren't going too well for me :(

Peristalsis
Apr 5, 2004
Move along.
Here's a quick question.

I have an object foo of type Bar with a string property called prop.

I execute the following:

code:
foo = Bar.find(1)
puts(foo.prop)
foo.prop.sub!("original", "replacement")
puts(foo.prop)
foo.save!
foo2 = Bar.find(foo.id)
puts(foo2.prop)
The output is:
original
replacement
original

If I instead execute this:

code:
foo = Bar.find(1)
puts(foo.prop)
foo.prop = foo.prop.sub("original", "replacement")
puts(foo.prop)
foo.save!
foo2 = Bar.find(foo.id)
puts(foo2.prop)
The output is:
original
replacement
replacement

So, it appears that using sub! with an object property changes the property, but the change doesn't save, whereas setting it as an explicit assignment does. Does anyone know if this is intended behavior, or if there must just be some other, subtle problem in my code making it do this?

Smol
Jun 1, 2011

Stat rosa pristina nomine, nomina nuda tenemus.
Model attributes that are not marked as serializable (stuff that is saved as json or yaml strings in the database, usually arrays) are only saved when they are marked to be dirty, i.e. when you use the setter methods. If you mutate the values directly, Rails doesn't know about that.

Gmaz
Apr 3, 2011

New DLC for Aoe2 is out: Dynasties of India

necrotic posted:

I see two options:

  • Add a main_link_to helper (or some such name) that always passes subdomain: false as an option
  • Setup a new link_to using alias_method_chain and default the subdomain option to false (but still allow it to be specified at call time)

The first option is more explicit, but requires you to use a new method for nearly all of your links. The second would be more "transparent", but could catch a new developer by surprise.
In the end I went with just changing footer and navbar links to absolute urls, cause I realized that's the only place I would have to make that change so it wasn't that big of a deal.

But in any case I appreciate the help.

Adbot
ADBOT LOVES YOU

necrotic
Aug 2, 2005
I owe my brother big time for this!

Smol posted:

Model attributes that are not marked as serializable (stuff that is saved as json or yaml strings in the database, usually arrays) are only saved when they are marked to be dirty, i.e. when you use the setter methods. If you mutate the values directly, Rails doesn't know about that.

While I wouldn't recommend it for this use case, you can force an attribute to dirty by calling foo.prop_will_change!. See the API Docs for more on dirty attributes.

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