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
kalleth
Jan 28, 2006

C'mon, just give it a shot
Fun Shoe
This is going to sound rather strange, but i'm bored and i fancy writing a rails app that some people will actually download and use. Anyone got any suggestions?

Adbot
ADBOT LOVES YOU

kalleth
Jan 28, 2006

C'mon, just give it a shot
Fun Shoe
Datamapper is pretty awesome guys; yes it involved switching my rails 3.x site from authlogic to devise, but that was minimal :effort:. No migrations, define properties once, auto migrate/upgrade... utterly awesome for development. Thought you should know!

:ninja: edit - plus, its faster and much nicer to use than AR.

kalleth
Jan 28, 2006

C'mon, just give it a shot
Fun Shoe

Evil Trout posted:

I spent almost a year working on a series of dating sites that used DataMapper, and let me tell you it was like pulling teeth. We had to make awful choices like sticking with a version that had known memory leaks or spending months upgrading to the latest version because they changed the API in huge awful ways.

Also, the killer feature of DM at the time, the Identity Map, doesn't work when you go across multiple databases.

If you find a bug in it, or have a question, good luck finding anyone to answer you. The IRC room would have 30 lurkers and nobody seemingly working on it or around at any time to answer questions.

Not my experience. The killer features of DM for me are only defining data model once (in the models) and proper o(x) scalability. Also, had issues moving AR to DM and theirc channel was more than helpful, providing that is you use Google and read docs first.

kalleth
Jan 28, 2006

C'mon, just give it a shot
Fun Shoe

Stup posted:

Been developing in Rails for a few months now and ran into some difficulties with this problem.

I'm trying to customize the error messages which are displayed from the Model. I asked around on stackoverflow but couldn't get anywhere with the suggestions. Currently I verify that there are no duplicated Members when trying to create a new Member and add it to a Team.


members_controller.rb


team.rb

I want to add some logic to my add_player method in team.rb that checks various properties of the player that is being added. This action will require multiple failure messages, other than 'Member already exists.' I've already got some methods in team.rb that return the values I want to check. I.e. Method position_count which counts and returns the number of players that fit a certain condition.

Really appreciate any help I can get!

You're going to do one of two things here.

The first is to pull the entire validation down to the model - preferred approach - using a custom validator (http://edgeguides.rubyonrails.org/active_record_validations_callbacks.html 6. Creating Custom Validation Methods)

i.e. in the model
code:
validate :method_name_as_symbol

def method_name_as_symbol
errors.add :member, "must be unique" if Members.find(member_id) or w/e
end
Within that method, you can either use errors.add(:fieldname, "message"), or alternatively, errors.add_to_base - see http://ar.rubyonrails.org/classes/ActiveRecord/Errors.html#M000302 for more info.

Alternatively, you can always do @model.errors.add_to_base in your controller, but I'd push the validation to the model...

kalleth
Jan 28, 2006

C'mon, just give it a shot
Fun Shoe
Yes, there is; you'd use a custom validator with validates :validationmethod in the model. So, for example

code:
class Team

 validates :cant_have_members_with_same_nickname

 def cant_have_members_with_same_nickname
   nicks = members.map { |m| m.nickname }
   unless nicks.uniq.length == nicks.length
     errors.add_to_base "Can't have members with duplicate nicknames"
     return false
   end
 end

end

kalleth
Jan 28, 2006

C'mon, just give it a shot
Fun Shoe

Stup posted:

This makes sense. I guess my Ruby isn't strong enough and I'm not quite sure how to build my conditional. Would you happen to know any good resources for me to read up on this?

Depends what you mean by 'conditional'. You mean your 'question'/'if statement' ? Most of the time when operating across a set your options are either each, map, or inject, depending on what the problem is.

kalleth
Jan 28, 2006

C'mon, just give it a shot
Fun Shoe

Stup posted:

For example, I can't understand the syntax used here:
code:
nicks = members.map { |m| m.nickname }

That's just a short way of doing a single-line loop in Ruby.

It's the equivalent of doing

code:
nicks = members.map do  |member|
  member.nickname
end
.map is a rubyist way of saying 'for each item in this enumerable, populate the output array with the value the following block evaluates to'

For example, for:
array = [{:value => "one"}, {:value => "two"}]

(an array of two hashes each with a :value element)
code:
array.map do |element|
  element[:value]
end
returns:
["one","two"]
Which is identical to doing:
code:
array.map {|e| e[:value]}
Ruby people like one-liners :)

Best starting point for that kind of thing is the ruby Enumerable docs - http://www.ruby-doc.org/core/classes/Enumerable.html

kalleth fucked around with this message at 00:21 on Jul 18, 2011

kalleth
Jan 28, 2006

C'mon, just give it a shot
Fun Shoe

enki42 posted:

Better still is:

code:
nicks = members.map(&:nickname)

Bastard :P yeah, that works

kalleth
Jan 28, 2006

C'mon, just give it a shot
Fun Shoe

Stup posted:

So I tried creating my own validation. I know it's ugly but please forgive me!

code:
	validates :cant_have_more_than_one_guard

	def cant_have_more_than_one_guard
		total_guards = 0
		members.each do |member|
			if member.gen_pos == 'Guard'
				total_guards = total_guards + 1
			end
		end
		unless total_guards <= 1
			errors.add_to_base "Can't have more than 1 guard"
			return false
		end
	end
When I try to load the team view, I get the following error:
code:
ArgumentError in MembersController#create

You need to supply at least one validation
Not sure where to go from here. I guess I don't really have experience using validations when they're not for some sort of form. Do I need to put this within the method I'm calling from the TeamsController? I tried this as well and Rails didn't know what validates is so I'm assuming that's not the right way...

Thanks again for your help!

My fault. See http://api.rubyonrails.org/classes/ActiveModel/Validations/ClassMethods.html#method-i-validate - you want validate, not validates, which is used for something completely different.

kalleth
Jan 28, 2006

C'mon, just give it a shot
Fun Shoe

Stup posted:

So I tried using validate and the error went away, but no errors ever pop up.

Here's my memberscontroller:
code:
  # POST /members
  # POST /members.xml
  def create
    @team = current_team
  	player = Player.find(params[:player_id])
  	@member = @team.add_player(player.id)

  	respond_to do |format|
  	  if @member.save
    		format.html { redirect_to(@team, :notice => 'Member was successfully added.') }
        format.js { @current_member = @member }
    		format.xml  { render :xml => @member, 
  			:status => :created, :location => @member }	
  	  else
    		format.html { redirect_to(@team, :notice => @team.errors.full_messages) }
    		format.xml  { render :xml => @member.errors, 
  			:status => :unprocessable_entity }
  	  end
    end
  end
Doesn't seem like the validation is doing anything. When I change it to unless 2 > 1, the create member action still goes through and there's no error displayed. What am I doing wrong?

Can I see the validate code from the model as well? Are you sure the create action still goes through; I.e. is something being persisted to the database? Perhaps call save! rather than save which will create an exception if the save fails?

A good way of debugging stuff is using the $ rails console command line to give you effectively an irb within your app environment.

This will let you do something like

> team = Team.find(:first)
#<Team:Object>
> team.add_player(Player.find(:first))
#<Team:Object player=#<Player:Object>>
> team.save!
> either backtrace or false or true

You can then use the console to inspect any errors.

kalleth
Jan 28, 2006

C'mon, just give it a shot
Fun Shoe

Bob Morales posted:

What are some good blogs/articles about setting up multiple front-end web servers with a load balancer (an all free-software Linux solution is preferred)?

Right now we have a single web server running Apache/Passenger and a MySQL database server. We'd like to have 2+ web servers due to traffic, and for redundancy. Our database is 20GB and grows about a gig a month, but a lot of that data is 2+ years old and not used anymore.

My boss was playing with the sliders on the Rackspace Cloud configuration page and basically said "We can get 4 8GB cloud servers for what we pay for our 1 server now..." but I tried to explain to him it's not quite that simple.

First thing I'd do is some kind of data retention policy to prune old, unused data. You can't just have a database grow all the time without some kind of attempt to clean it. Apart from the obvious storage concerns, old data is useless data that pollutes your data stores usefulness.

My personal thoughts are if you want to go the balancer route properly, i'd look at some other rack servers; thin/rainbows/mongrel - instead of passenger.

That way you can split it out - a frontend web server running apache/nginx which is the 'entry point' to your users - feeding out over an internal network to several different balancers using mod_proxy. These balancers can connect to your database server individually.

Blogs, not too sure, but that's the approach I use; when using nginx or apache as a simple pass-through for the balancers and a dedicated database box, you're not going to hit capacity on either of those before you have a rack full of balancer servers.

kalleth
Jan 28, 2006

C'mon, just give it a shot
Fun Shoe

Bob Morales posted:

How do you keep the web servers synchronized? Capistrano can push to more than one server but we have user data (images etc) that aren't in there. I take it we would need to implement some sort of shared storage between hosts?

Depending on your level of traffic, your frontend apache / nginx server can 'act' as a CDN for static assets - i.e. images/etc.

Your mod_rewrite rule that redirects requests to the balancers is normally only set up to forward to the balancers if the request path doesn't exist relative to the document root.

Or use Chef. Or Puppet.

Or just use heroku.

kalleth
Jan 28, 2006

C'mon, just give it a shot
Fun Shoe
holy moly, ruby 1.9.3 and rails 3.1.1 are a pretty amazing combination, speed-wise, compared to even 1.9.2 and 3.0.

I have no proper metrics for this, but the app just feels really responsive, sub~20ms response times for each page request/load, etc.

Got a web application up atm on a 512mb ram vmware VM (single core) used by approx 50-60 people at once, on a single thin balancer, and the load is negligible.

And that's without caching! I'd love to see a 1.9.3 + 3.1.1 comparison vs a php framework, right now.

kalleth
Jan 28, 2006

C'mon, just give it a shot
Fun Shoe

Physical posted:

Also what is the deal with always having to inherit form an object?

Literally everything in Ruby is an Object. '1' is an object of the String class, 1 is an object of the Fixnum class.

Physical posted:

Like, how do you know which objects to inherit from? Where is the list at? Right now, those first two parts are really losing me, the missing {} and () sucks too. Why do I have to right end if I can just do } I like the way it looks much better.

In the examples given, the models and controllers (Person, PersonController 'classes') build on functionality provided by rails, hence they inherit from ('extend') ActiveRecord::Base class which then provides an ORM around using that object (having it go to the database to retrieve itself, for example, and allowing you to 'save' it, etc).

The controller code is called in specific ways with specific prefixes/suffixes etc hence extending from ApplicationController (which extends from some other ActionController::Base, i think).

Basically, if you didn't extend these classes, you don't get the functionality of rails.

Physical posted:

And is the lowercase person the same as the uppercase Person ?

code:
person = Person.find(:first)
'person' is an instance of the Person class -- in this case, the 'first' instance that could be retrieved from the database (this is equivalent to doing SELECT * FROM people LIMIT 1).

kalleth
Jan 28, 2006

C'mon, just give it a shot
Fun Shoe
Just throwing this out there...

Am I the only one who doesn't like using the generators and just writes the migration and class by hand? It's not hard, self.up, self.down, blank Model < ActiveRecord::Base, etc.

It's not that I don't trust generators, i'd just rather learn how to code the stuff a generator does for me, and it doesn't even save that much time :(

kalleth
Jan 28, 2006

C'mon, just give it a shot
Fun Shoe
Use simple-navigation for nav - https://github.com/andi/simple-navigation - and cancan for authorization :)

kalleth
Jan 28, 2006

C'mon, just give it a shot
Fun Shoe

8ender posted:

We use simple-navigation on three of our apps and its versatile as hell.

I go out for beer with the current maintainer of simple-navigation now and again :P (mjtko, not andi)

Adbot
ADBOT LOVES YOU

kalleth
Jan 28, 2006

C'mon, just give it a shot
Fun Shoe

A MIRACLE posted:

That's not so bad. I'm on a team that writes migrations that look like
Ruby code:
class CreateSuperUser < ActiveRecord::Migration
  def self.up
    add_column :users, :is_superadmin, :boolean
    u = User.new
    u.email = #
    u.name = #
    u.is_male = 1
    u.is_subscribed = false
    u.password = # yes they really do this
    u.password_confirmation = #
    u.status = 1
    u.zip_code = '01128'
    u.is_superadmin = true
    u.save
  end

  def self.down
    remove_column :users, :is_superadmin
  end
end
I wish I were joking.

Notwithstanding that that should be a database 'seed' rather than a migration, don't use models in migrations. Like that, at least.

http://gem-session.com/2010/03/how-to-use-models-in-your-migrations-without-killing-kittens
http://complicated-simplicity.com/2010/05/using-models-in-rails-migrations/

Edit: Also, kill yourself. Then quit.

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