Ruby on Rails -- not grokking - ruby-on-rails

I've been learning a lot about web technologies recently and I want to put together a neat little website to play with html, css, javascript, flash, and what have you.
I know that as far as the web browser is concerned all I need to do is send a text file (usually HTML) from my server using HTTP over TCP.
I've gone through a couple of Rails tutorials by now but I am having a lot of trouble getting things to work and understanding how the components work together even if I could get it to work by blindly following said tutorials to the letter.
I think I understand the MVC concept. Obviously the business model of an application makes sense to be kept separate from the view implementation, etc. Sure, that's fine. From what I understand RoR needs (?) a database. Sure, when my website grows to a point where I need to track customers and crunch data, I will want that.
But where do I get at the actual functionality? Where do I specify how my server responds to requests from browsers? Shouldn't this be straightforward? Do I need to set up a database just to get my "hello world" page up?
I think what might be happening is that Rails is designed to do something that I don't need (yet?). It does many things for me that I don't understand, and in order for me to be comfortable I would have to dig through a lot of material to figure it out.
What brought me to this point is, I am looking for the "next step" after this little server I was playing with:
require 'socket'
server = TCPServer.open(8080)
loop {
Thread.start(server.accept) do |client|
client.puts(Time.now.ctime) # server sends dynamic page consisting of current time
client.flush
while (str = client.gets) do
puts "recvd >> "+str # show what server gets from client
if str.chop.length == 0 then break end # detect end of transmission
end
puts "done"
client.close
end
}
This little bit of code is more than halfway there to what I need it to do. I got stuck on something pretty silly. I still don't know how to just take a file on disk and send it to the client. I figure i'd open a stream to the requested file and pipe it over to the socket... No idea how to do that in ruby. So I figured, hey, maybe Rails'll do it for me.
Now I follow a bunch of directions, finally get the server running on mongrel, and I try this: ruby script\generate controller MyTest and still get a "Routing Error" when I open it up in the browser. I get a giant ugly stack trace on the cmdline. Screw this!
Clearly I should be taking a class that will show me how to use Rails and more importantly, whether or not it is overkill for my purposes. So... should I keep trying to figure it out? If so, can someone show me a good tutorial, or explain to me why the tutorials I have seen aren't helping me?
Should I just try to use EventMachine to make my server? I just want to make a nice simple fast web server.
Thanks for reading. :)

You are way, way over-thinking things. Not that that's bad at all - it's great you want to learn the innards of how everything fits together and works, but Rails handles the vast majority of stuff like this for you.
For development purposes you are most likely going to use the Ruby webrick "server", which you can run from your applications home directory by doing: ruby script/server
Now, whenever you go to your application, which is by default going to be running at: http://localhost:3000/ , this server will process your requests and return the html for the appropriate view. If you have your app created and have a database set up, going to the url I mentioned will show you a "welcome aboard" message from Rails, letting you know everything is up and running. Later on when you push your app into production you'll be using the Apache server, but still, you won't have to worry about the things you mentioned in your question.
It is entirely possible to use Rails without a database, check out config/environment.rb:
# Skip frameworks you're not going to use. To use Rails without a database,
# you must remove the Active Record framework.
# config.frameworks -= [ :active_record, :active_resource, :action_mailer ]
Just uncomment that last line and make sure you leave active_record in it.
I think what is going to help you best overcome your confusion is to research how Rails routing works, which is controlled by the config/routes.rb file. I think this will help you understand how Rails accepts and reacts to incoming requests.
And Rails is actually perfect for building little sandbox websites to play around with - once you get over the initial learning curve you can get stuff up and running very fast.

Your time server in Rails:
# app/controllers/time_controller.rb
# after ./script/server, available at:
# http://localhost:3000/time/
class TimeController < ApplicationController
def index
render :text => Time.now.ctime
end
end
Database not needed. (You do need to remove ActiveRecord from the frameworks stack as Zachary shows in his answer).

Rails is not appropriate for this. You might be better off using apache for a static file server. Or, you could rewrite your socket server like this:
require 'socket'
server = TCPServer.open(8080)
loop {
Thread.start(server.accept) do |client|
client.puts(Time.now.ctime) # server sends dynamic page consisting of current time
client.flush
while (str = client.gets) do
puts "recvd >> "+str # show what server gets from client
if str.chop.length == 0
client.write File.read(the_file_to_send)
break
end
end
puts "done"
client.close
end
}

Related

Event listener for Rails

I want to try to make a simple real-time chat Rails web app, but I thought I would need some kind of let's call it "event listener" to be able to keep track of sent messages so the receiver user's feed get updated with the new message. Also, for the Typing... notice box.
I hope I explained myself.
I guess I could do it in a very troglodyte way to achieve this like follows:
main.js:
while(true) {
$.get('/user-you-are-talking-to/are-there-new-messages', function(data) {
if (data['are_there_new_messages'] === true) {
$('#conversation').append(data['new_message']);
}
});
}
conversation_controller.rb:
# routed by /user-you-are-talking-to/are-there-new-messages'
def new_messages?
unless #new_messages.blank?
#json = []
#json[:are_there_new_messages] = #new_messages.count > 0
#json[:new_message]= #new_messages.shift
render json: #json
end
end
But well aside than the fact that I didn't test that code, a while loop and constant requests to the server seem like a really really bad idea, obviously.
I would like to know if Rails has a built-in feature like this, but as far as I know it doesn't, unlike frameworks I've worked with like Laravel. If there's not a built-in tool for this, how can I do this app?
Real time apps are usually done with websockets.
https://github.com/eventmachine/eventmachine
https://github.com/igrigorik/em-websocket
Or if on a hosted service you can use a publish/subscribe service such as Pusher or PubNub.
Otherwise, you would do polling which is what you have in your example.
Rails 5 will come with Action Cable:
Action Cable seamlessly integrates websockets with the rest of your Rails application. It allows for real-time features to be written in Ruby in the same style and form as the rest of your Rails application, while still being performant and scalable. It's a full-stack offering that provides both a client-side JavaScript framework and a server-side Ruby framework. You have access to your full domain model written with ActiveRecord or your ORM of choice.
But while you're waiting for it, you can use a number of existing solutions, some of which #dinomix listed.
Another option is Faye (never used, but heard good things).

Several PhantomJS calls in a RoR application

I have a RoR application that given a set of N URLs to parse, will perform N shell calls for a given PhantomJS (actually is a CasperJS) script.
So,
Right now I have something like this:
urls_to_parse = ['first.html', 'second.html',...]
urls_to_parse.each do |url|
parse_results = \`casperjs parse_urls.js '#{url}'\`
end
I have never done this before. Launching shell scripts from a RoR/Ruby application, so I am wondering if this is a good approach and what alternative may I have. So, why I use PhantomJS in combination with RoR?
I basically have an API (RoR app) that keeps receiving urls that need to be parsed. They need to be parsed in a headless browser manner. The page actually needs to be rendered (that's why I don't use Nokogiri or any other HTML parser).
I am concerned about putting this up to production performance wise, and before going forward I would like to know if I am doing this correctly, or I can do it in a better way.
It's possible I thought about doing the same thing, but even with a headless browser I would be really concerned about the speed and bandwidth your server is going to need to have. I use capser in conjuction with Python and it works very well for me. I read stdout spit back from firing the casper scripts, but I don't parse and scrape on the fly like you're talking about doing. I would imagine it's okay, but ideally you already have a cached database of results when people search. Maybe if it is a very very basic search you'll be okay, but I don't know.

CakePHP and Rails: slowly port old php functionality to new rails

I am a rails developer working on a cakephp site. The more work they send me, the more php code I write and thus the more dependence on php we introduce. What I want is to stop writing new features in php and start writing them in rails. Our resources are limited and the existing php site is huge so a full port from cake to rails is not possible.
Is there some way to write new features in a rails app while maintaining and allowing access to all the functionality of the old php (and vice-versa)?
It seems I would need a route aware app to traffic requests to either php or rails, but then we run into the issue of, for example, existing user functionality written in php not being available to the rails app and vice-versa.
What about something to translate ruby into php? That way I could start writing my model stuff in ruby/rails rather than php.
I feel like my question is muddled by the fact I do not know how to ask the questions I want to answer, so hopefully this is understood.
As always, thanks in advance!
One approach that you may find useful is to leverage the power of your web-server to properly re-write and delegate requests to two different systems. If you can design your new Rails application to use the same database records as the old one, with models mapping to the old tables directly, and ensuring that sessions established by one are valid in the other, you have a lot of latitude in how you go about doing this.
Apache has a very full-featured URL rewriting and proxying system that can be configured to direct "legacy" parts of your site to an existing set of PHP scripts while directing all other traffic to the new Rails application. You will need to be careful to ensure the design of both applications are nearly identical or it may seem strange to users.
Another approach that helps ensure a consistent appearance is to strip out a lot of the theme from your PHP application. By creating very bare-bones pages that only expose the required functionality on each page, Rails can fetch these by passing through any relevant session authentication information and re-frame them in the right layout.
This way you can preserve existing functionality and have it embedded inside your new application. You can use something as simple as open-uri or the curb gem to handle this HTTP-level delegation.
You would end up with controllers that look like this:
class PaymentController < ApplicationController
def index
#content = fetch_legacy_url('/payments/index.php'))
end
end
The fetch_legacy_url method would create an HTTP fetch request that includes the required headers, cookies, and so forth, and return the response body. Your view then ends up looking something like this:
<%= #content =>
From there you can shunt parts of the PHP layout over to the Rails app piece by piece. For instance, ripping out large chunks of static HTML and putting them in the Rails template would reduce the amount of actual PHP code you have to port.
It's a bit messy to maintain two applications in parallel, but as you point out the alternative is to keep accumulating technical debt and making the inevitable re-write that much more significant an undertaking.
The first step would be to experiment and see if you can create a Rails environment that uses your existing data, or at least the data relevant to the new functionality you intend to build out.

How to set a minimal Ruby page on a webserver that can add / edit / delete records?

I am trying to add a page on dreamhost.com to display
record = Record.find(params[:id]) # such as Record.find(1)
print record.content # to show content of this record
and that's it... probably using sqlite or mysql, and want to have the ability to add a record, similar to Ruby on Rails's scaffold.
If using Ruby on Rails, it is probably too big for such a simple purpose, but if I use Sinatra, then it looks like I have to start it on a port (and can't start it on port 80 because it is the dreamhost.com's port)
Can Sinatra or any tool or framework fit this purpose?
Go with Rails
Dreamhost offers Rails already installed and at no extra cost. And knowing Rails will certainly be more useful to you in the future than knowing Sinatra.
So, I don't see the benefit in Sinatra unless you are hosting the server.
Since Rails is a framework, it will give you a basic application easily, despite it's massive internal complexity.
I know this doesn't exactly answer the question, sorry about that, but on a shared-hosting site you will have limited opportunity to fiddle with the configuration. It's easier in this case to go with Rails.
Rails isn't really that heavyweight. Unless you need your "app" to be very high performance, Rails is probably a good solution that'll let you have this up in a matter of a couple hours.
That said, I'm sure Dreamhost has a way for you to run a Sinatra app within Phusion.
I wonder why nobody mentioned Padrino yet. It is lightweight and provides you with a simple admin interface!

Getting Started with Ruby & Ruby on Rails

Some background:
I'm a jack-of-all trades, one of which is programming. I learned VB6 through Excel and PHP for creating websites and so far it's worked out just fine for me. I'm not CS major or even mathematically inclined - logic is what interests me.
Current status:
I'm willing to learn new and more powerful languages; my first foray into such a route is learning Ruby. I went to the main Ruby website and did the interactive intro. (by the way, I'm currently getting redirected to google.com when I try the link...it's happening to other websites as well...is my computer infected?)
I liked what I learned and wanted to get started using Ruby to create websites. I downloaded InstantRails and installed it; everything so far has been fine - the program starts up just fine, and I can test some Ruby code in the console. However my troubles begin when I try and view a web page with Ruby code present.
Lastly, my problem:
As in PHP, I can browse to the .php file directly and through using PHP tags and some simple 'echo' statements I can be on my way in making dynamic web pages. However with the InstantRails app working, accessing a .rb or .rhtml page doesn't produce similar results. I made a simple text file named 'test.rb' and put basic HTML tags in there (html, head, body) and the Ruby tags <%= and %> with some ruby code inside. The web page actually shows the tags and the code - as if it's all just plain HTML. I take it Ruby isn't parsing the page before it is displayed to the user, but this is where my lack of understanding of the Ruby environment stops me short. Where do I go from here?
AMMENDMENT: This tutorial has helped me immensely! I'd suggest anyone who's in my position go there.
First of all, you must disconnect the relationship between files and URLs.
Rails uses an MVC approach, which is worlds-different from scripts-based approach like ASP/PHP
In classic PHP, you have something like this
Server> Server started, serving scripts from /usr/jake/example.com/htdocs/
User> Please give me /home.php, thanks!
Server> OK, /home.php is mapped to /usr/jake/example.com/htdocs/home.php
Server> Executing /usr/jake/example.com/htdocs/home.php
Server> OK, it prints out a "Hello World!", send that to the response.
User> Ok, /home.php shows "Hello World!"
However, most MVC framework (Rails included) goes something like this:
Server> Server started, initializing routing modules routes.rb
User> Please give me /home, thanks!
Server> OK, /home, per the routing module, is handled with action ShowHomepage() in controller FrontpageCtr
Server> Execute FrontPageCtr.ShowHomepage()
Ruby> FrontPageCtr.ShowHomepage() prints "Hello World!"
Server> OK, sending "Hello World!" down the pipes!
User> Ok, /home shows "Hello World!"
As you can see, there is no connection between what the user put into the addressbar and any script files
In a typical MVC framework, processing a request for any URL goes something like this:
Look in the Routing module (which in the case of rails is defined in routes.rb)
Routing module will then tells the server which "Controller" and "Action" should be used to handle the request.
Rails then creates the Controller and invokes the Action function whatever that might be
The result from the action then gets "Rendered", which, in this case, is supposedly rendering the .rhtml file as actual HTML... there are, of course, other kinds of results e.g. send the user to another URL and whatnot.
The result is then written out to the response stream and displayed by the user's browser.
In short: You must disconnect the notion of scripts and URL first. When you're building MVC websites, they are almost always NOT related in a way that most people understand.
With that in mind, you should be more comfortable learning Rails and MVC way of life.
I'm not a Rails pro so please correct me if I'm mistaken on any part.
I would suggest buying and working your way through Agile Web Development with Rails, an excellent book and a very practical way to learn both Ruby and Rails. It's available instantly in a variety of electronic formats, plus you can get paper copy if you prefer that.
From what you describe you have a fundamentally flawed understanding of how Ruby and Rails, in particular, works. I suggest you spend some time with the book then come back and ask about anything that you get stumped on.
Rails is "parsing the page before it is displayed to the user", if you locate the right file to modify ;-) Those files to be modified are under the following folder(s):
app/views/...
That's the short answer. For a comprehensive one (for a newbie), I highly recommend: http://guides.rubyonrails.org/getting_started.html
Getting started with Ruby on Rails is something that is a little daunting at first, but after you get started it gets a lot easier. After running Ruby on Rails bootcamps for Startup Accelerators, Harvard Business School, in Times Square, Boston, and Pittsburgh, I started http://www.firehoseonline.com. It's a video tutorial to get started, so you should check out that site.
My advice is to learn as much as you can by actually writing the code. Don't get caught up too much in the details and the specifics. If a tutorial gives you some code to write, and some information, and you don't absorb all the information at first, keep going. Afterwards go back to the material, and once you have gone through the whole process of writing your first application a lot of the pieces will fit together.
As far as your question about opening the php files directly, using the MVC pattern is a little different. You need to setup a the controller, the views and the routes before you can start putting code into .rhtml (or now .html.erb) files. Because of this architecture you'll be able to write a lot of awesome, clean code, super fast, but it can be a bit tricky to wrap your head around (if you REALLY want to write code that way you can with other frameworks, but trust us that this way is better). Stick with it!
Keep your coding mojo high!
Aloha,
Ken

Resources