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
necrotic
Aug 2, 2005
I owe my brother big time for this!

kayakyakr posted:

Ah, so gems like figaro still have quite a bit of value.

We use dotenv which reads a .env file if it exists. It works out really well, as we use foreman to export our Procfile for the init system which can handle .env files (either when invoking foreman directly, or using its export functionality).

.env files are also valid shell files, so you can use source to pull in any environment variables if you need them.

Adbot
ADBOT LOVES YOU

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

MALE SHOEGAZE posted:

In other news, I figured out that erb will let you do this:

code:
<%- 
def render_details(details)
  details.each do |k,v|
-%> 
    <details>
      <summary>
        <%= k.to_s %>
      </summary>
        <div style="padding-left:30px">
<%-   
          if v.class == Hash
            render_details(v)
          else 
-%>
            <%= v %>
<%-       end 
%> 
      </div>
    </details>
<%- 
  end 
end
render_details({omg: {look: "it's", at: :loving }, becky: { this: :bad, code: "!!!" } }  )
%>

Why wouldn't it? You could probably do it in haml, too. But... Why?

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

MALE SHOEGAZE posted:

Because partials are obviously not enough for people, so I constantly see object methods that return "HMTL CODE".html_safe, which are then rendered in the view. I'm just surprised I haven't seen this.

You could even say, define a bunch of these methods in your application.html.erb then use them whenever you want!

That entire idea really belongs in the coding horrors thread.

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

Pollyanna posted:

Using send in an instance method doesn't seem to work, cause it seems to think that the method being called is a method on the Class, instead of a method on the main application. Do I have to pass the method itself in, somehow?

Option 3 (which is slightly different from kayakyakr's Option 2) is to use Object#method to get an instance of the Method:

Ruby code:
{
  action: method(:create_party)
}
This gives you back a Method object which behaves much like a Proc.

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

fletcher posted:

Why does /var/lib/gems/1.9.1/doc/fog-1.23.0 take up 660MB? I have a couple different versions in there too, taking up tons of space

Fog is thoroughly documented and supports a ton of services. You often don't need the docs locally (thanks to rdoc.info), and I recommend creating a ~/.gemrc or /etc/gemrc with the following:

code:
gem: --no-ri --no-rdoc
edit: I went ahead and installed Fog 1.24.0 with ri and rdoc and my folder is only 100M. My entire `gem env gemdir`/doc dir is only 118M after installing Fog. Do you have more than just the ri/rdoc versions of the docs available in the Fog folder?

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

Molten Llama posted:

Preferably --no-document today unless you're rocking an extremely old version of Rubygems for legacy applications.

--no-ri --no-rdoc has been deprecated since ~2.0 and will (eventually) be going away.

I did not know this! Time to update my rc file and change what I tell everyone at work.

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

Pollyanna posted:

Huh. That answers a lot of my questions, actually. I was always confused by Rails' "models only data, controllers only processing/logic" dealio. I'm trying to make a model output its characteristics in a particular order now, and I'm having trouble figuring out whether to do that in the Model, Controller, or View. I want to say the Model, going by rspec-rails documentation, but apparently not...?

In terms of output for an API? Use jbuilder views for that.

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

Doh004 posted:

I'm just slowly working my way through my first rails application and just rolled my own user authentication. I know there's tons of gems out there that do this already though... but it's a good learning experience, right? :ohdear:

It is good knowledge, but after you've done it once start using Devise. Its amazingly powerful and really quick to get all of the functionality you need for authentication (including pluggable schemes, like oAuth and 2FA).

Authorization is a different beast. I used to recommend CanCan, but its been discontinued (although the community has picked it up with CanCanCan). I've started using Pundit, which is basically helpers for writing authorization rules inside of POROs, and I have been loving it. It's a bit more verbose, but makes testing and understanding the system so much easier.

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

Thalagyrt posted:

I honestly disagree on using Devise for everything. We've rolled our own authentication in-house and couldn't be happier. Devise didn't do what I wanted - it got me 95% of the way to where I wanted to be, then I spent more time than it took to roll my own authentication wrangling Devise to sort of kind of maybe do what I wanted. I ended up ripping almost all of devise's built in functionality out, then realized I may as well roll my own. It meets a specific, and admittedly common, use case, but if you're not in that exact use case it falls apart spectacularly. This is the case with the majority of gems that try to be a solution for everyone like that.

This is true for any language and any set of 3rd party libraries: they work for the most common cases, but once you need something specialized (I would be interested in what use case you had that didn't fit) rolling your own is generally the best approach.

quote:

Pundit's no exception to this one-size-fits-all problem. Pundit assumes that authorization is going to be based on roles on the user, and the second you want to bring a secondary object (user has x permissions on account y and z permissions on account q, for example) into the authorization scope, Pundit falls apart without extensive modification. The whole concept of doing authorization in functions that take two objects is kind of silly anyway. Why should you have both a function to check if a user has rights on an object as well as a scope to return only the objects the user has rights to? Simply use the scope all the time. Check out Consul for an example of that. It's far more flexible than Pundit and can handle extremely bizarre authorization requirements very elegantly.

I had not heard of Consul and will check it out. I do like the idea of scope-centric authorization.

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

Thalagyrt posted:

Henning (the author) has a great talk about Consul if you want to watch it!

http://bizarre-authorization.talks.makandra.com

Excellent, thanks!

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

The Milkman posted:

I don't suppose there's a way to have basic http auth always reprompt for credentials?

Not a built-in way. You can hack it by redirecting them to a URL with a bogus username, but its not very friendly.

necrotic
Aug 2, 2005
I owe my brother big time for this!
code:
@some_array.to_json

That will print out a json encoded version of the object, which can go directly into your javascript block.

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

Pollyanna posted:

We're being taught differently, as we use Rails as an API server (database, AJAX, etc.) and don't bother to use the asset pipeline or Javascript libraries since it's headless. Instead, we create separate front-end static asset servers that hand out HTML, CSS and JS to the client which then access the API server to render everything. Is this common?

We're doing this now at work. Our monorail, which contains the old dashboard and all of our business logic, now exposes an api that a separate project speaks to. The assets are served up through the monorail in the end (well, a cdn, but the view lives in the monorail), but we are eventually moving that away too.

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

kayakyakr posted:

This also sorta makes sense if you haven't required your factory files in some form or fashion.

Yeah, do you have the factory_girl_rails gem? It handles loading factories automatically. It looks like you do based on the use of generators. I've never had this problem myself. Maybe something weird with your bundle file and test not finding factory_girl_rails? :iiam:

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

Pollyanna posted:

I forgot to add require 'rails_helper' to my spec files. :shepicide:

Yeah that'll do it. Glad it was a dumb mistake and not some arcane issue with gem deps!

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

Peristalsis posted:

I'm sure this is heresy or something, but is RSpec really that much better than the built in testing suite? I found a quick introduction to it in one of the books I read (Eloquent Ruby, maybe?), very poor documentation and examples online, and I just didn't see how it was fundamentally better than the unit tests and fixtures. Are there tests I can do in RSpec that I can't do with the built-in testing framework, or is it just supposed to be more slick and fashionable?

I'll admit that I find it tiresome that every Rails tool I use has something newer/shinier/better that everyone says I should be using instead (except when I shouldn't) - Pry instead of the built-in debugger, HAML instead of erb, RSpec instead of whatever the built-in tools are called, and so on. I'd rather get proficient at using a set of good tools, than constantly be in learning curves for things that are only marginally better, and possibly not as stable.

As an example, we recently updated our Ruby and Rails versions, which made the built-in debugger almost useless. So, we're using Pry now, but I get some weird behavior from it sometimes, as well as some memory errors in my testing. I don't know if Pry isn't quite ready for prime time, or I just don't know how to use it correctly. I also don't know if Pry is causing the memory errors, or if something in my code changes is doing that. So, everything slows down and gets harder just because we want to recapture the same functionality we had before upgrading.

Sorry, I'll quit ranting now.

RSpec doesn't let you do more than the core Test framework, but it is far more expressive. If you're doing BDD/TDD its a much stronger tool as you can literally describe your code before your write it out. Then you write the code and it all works. You can probably do it successfully with Test, and really it boils down to personal preference. I can use either, but if I am doing TDD I vastly prefer rspec.

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

Smol posted:

Maintaining rails apps programming is hard without good test coverage. Don't even try to skimp on tests, kids.

Extends to libraries as well.

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.

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)

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.

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

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.

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.

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

xenilk posted:

I have a question for folks who work professionally in a Ruby environment. What type of testing do you use? Reading a lot it seems like Test::Unit, Minitest and RSpec are the most popular but I can't really decide which way I should go that I would benefit the most in the field.

There's no "right" way to go about testing. RSpec is definitely popular, but I think Test::Unit holds its own in a large part of the field. I have heard less about minitest, but I know its also a relatively new player on the block.

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

Doghouse posted:

Does anyone know of a ruby reference resource I could use for the basics of Ruby, coming from a C#/Java background? I'm having trouble getting a handle on the basic syntax for an assignment. I'm trying to set up a hash as a class variable and I can't even figure out how.

code:
class Fubar
  attr_reader :hash

  def initialize
    @hash = {
      :foo => :bar
    }
  end
end

c = Fubar.new
c.hash[:foo] # => :bar
http://mislav.uniqpath.com/poignant-guide/book/ is a good starter resource.

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

EVGA Longoria posted:

That's an instance variable. A class variable would be @@hash.

Then here:

code:
class Fubar
  def self.hash; @hash ||= {}; end
end

Fubar.hash
You can use class variables, just be careful. Inheritance is fucky with them:

code:
$ cat test.rb
class Foo
  @@buttes = 'lol'

  def self.buttes; @@buttes; end
end
class Baz < Foo
  @@buttes = 'fart'
end

puts Foo.buttes
puts Baz.buttes
$ ruby test.rb
fart
fart

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

MALE SHOEGAZE posted:

What does this mean?

CodeClimate grades your code from F to A based on some heuristics. With an A being the "best".

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

Buckhead posted:

I need to process a string word by word and see if certain words match a condition, then compile the string back together. Basically, I am pulling social media posts and want #s and @s to show up in blue.

Does anyone have any experience doing something like this? In that past, I would probably use something like PHP's explode() function, but perhaps there are more elegant methods.

If you want to avoid using gsub, you could split and then join the string:

Ruby code:
require 'set'
def mark_things(str)
  markable = %w(#s @s).to_set # Use a set for O(1) include?

  str.split(' ').map do |word|
    if markable.include?(word) # If it's not specific words, and literally any hashtag or user, then do `word =~ /^#|@/` instead
      "<span class='marked'>#{word}</span>"
    else
      word
    end
  end.join(' ')
end

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

Gmaz posted:

That's nice, never realized this.

Yeah, its implemented as a Hash underneath, so anything looking for a specific value just maps to a hash key.

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

kayakyakr posted:

you suck where's railsconf this year?

ATL

I should've gone considering its right around the corner. Oh well!

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

Buckhead posted:

I am being returned a hash from an API with two identical keys. I need to save the first and second value to separate variables.

Looks like it will always be two values, so I'd just do this:

Ruby code:
postcard.thumbnail_front_url = newcard['thumbnails'].first['medium']
postcard.thumbnail_back_url = newcard['thumbnails'].last['medium']
edit:

Also, there's Enumerator#each_with_index so you don't have to increment your own counter.

necrotic fucked around with this message at 18:14 on Apr 21, 2015

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

KoRMaK posted:

e: Fixed it, changed some init settings and it started working. Wierd that it required me to exit the terminal though. I think it was fixed by remove config.reload_classes_only_on_change = false

Yeah that setting will do it. And rails will only reload files from app/ and lib/, config/ file changes require a full reboot of the app. Not sure why you had to exit your terminal (I assume you mean like Terminal.app or iTerm2.app, not the rails console).

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

KoRMaK posted:

Thanks for the suggestions guys.

Yes, it's a queue that I'm building. So I'm checking out delayed job, resque etc. I started getting serious about delayed job, but I think I may have an issue with it. I need to limit how many of these things run per second. It doesn't seem like their is a way to manage that in delayed job. Is there a way I can tell it to only run X number of jobs per second?

If not, then I'd have to figure out a way to limit that.

Most queue systems give you a way to limit the number of workers, not a strict per/s limit. Once you figure out how long the task takes you can kind of limit the work per/s by lowering/raising the number of workers, but it won't be perfect.

I'm not sure about Delayed Job or Resque, but our job system lets you change queue reading strategies which would let you create a strategy that throttles when receiving messages. This would limit you to one process with an option for multiple threads, though you could do multi-process support with some work.

necrotic
Aug 2, 2005
I owe my brother big time for this!
We use Chore, which we wrote internally and recently open sourced. Documentation is a little lacking, but the interface for the different types of strategies is pretty straight forward. We don't have anything that needs throttling internally so there's no mechanism built-in to handle it, but adding it to a custom Queue consumer wouldn't be all that difficult.

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

kayakyakr posted:

Reminder that ActiveJob was promoted to a first class citizen in the most recent Rails, so if you pick a gem to go with, you should probably pick one that integrates with activejob

Yeah, we should make an adapter for chore. Not a priority for us as we're still on 3.x :(

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

MasterSlowPoke posted:

I'm just about to use Resque, is there anything I should know about it or should I jump to something else before I'm in too deep?

Resque should be fine. I wouldn't use it at scale from past experiences, but if you go the ActiveJob route switching out backends is dead simple.

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

KoRMaK posted:

I don't get it. But I didn't get Rails either. Why is Crystal eye popping good?

If you like Ruby but want an actual type system, I guess. I wish the homepage had more info, and that the manual wasn't split into a million small sections.


Seriously, what the gently caress: http://crystal-lang.org/docs/syntax_and_semantics/comments.html

necrotic
Aug 2, 2005
I owe my brother big time for this!
The proper way to make sure your test database is correct is rake db:test:prepare. Not sure why it stopped happening on db:migrate for you, but use the test:prepare version instead.

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

Peristalsis posted:

If plain old command-line ssh has an option to suppress the additional password prompts, I guess I could just construct a command string to use with backticks in the ruby code, if I can't find a similar option in net-ssh. We've had to do similar things one or two other times with ruby features that were slower than their CLI counterparts.

There is not a way to remove the prompt for password-based logins. The proper way to solve this situation is using key pairs, or possibly through an LDAP system.

Adbot
ADBOT LOVES YOU

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

KoRMaK posted:

Yea I saw that, but it seems like not a good practice for some reason. I guess that my reason for feeling that way is that I don't see a reason to have more than 1 user be in charge of "rails" things.

You may be able to get that by making an rvm-ro group and giving it readonly access to the RVM install.

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