Beginning Rails 3 (Expert's Voice in Web Development)

Category: Programming
Author: Rida Al Barazi, Cloves Carneiro Jr., Cloves Carneiro
All Stack Overflow 7
This Month Stack Overflow 2


by anonymous   2017-08-20

Wow, that's a lot of questions. First, let me recommend you pick up a copy of "Beginning Rails 3", which is a fantastic introduction to Rails which would answer all of these questions and help you quickly become a very solid rails programmer.

Second, here are some basic answers for you:

1) You shouldn't browse to products/create, you just browse to products/new. Whenever you browse to a URL you're sending a GET request. The "new" action expects a GET request, but the CREATE action expects a POST request. POST requests are generated by submitting forms.

Therefore, the flow is like this:

The NEW action is used to create a form appropriate to the model in question (products). When you submit the form from products/new it will POST to products/create, which will trigger the code in the CREATE action.

The relationship between NEW and CREATE is mirrored in EDIT and UPDATE. Ie, to change an object you browse to products/123/edit, and from there you submit a form which triggers the UPDATE action.

This all falls under what is called "RESTful" design, which is really the heart of how Rails works. You may want to learn more about REST, here's a good place to start.

2) form_for gets data from the controller -- but in the case of the NEW action it isn't getting data, just an empty (new) object. form_for is a helper which receives an object and from that object determines some of the HTML that needs to happen in order for the forms that are generated to correctly interact with your controller.

The same thing happens when you load a page at products/edit, but the difference is if you pass form_for an existing (not new) object, it will populate the fields of the form with the existing values from the object.

3) The transfer of control is happening via the HTTP request as set up in the HTML <form> tag. This is part of the 'magic' of rails, it handles the linkages between the browser and the controllers for you so you don't have to worry about it.

4) I don't usually use redirect_to(@product), but I would expect it to take you to the page for the product you just created, ie: products/123 where 123 is the ID of the product.

I hope this helps, but please do consider picking up the Beginning Rails book: it's very very good, you can progress through it in about a week, and you'll save TONS of time by getting started on a solid foundation rather than wandering through code like this that is totally unfamiliar to you.

by anonymous   2017-08-20

So, one thing is you're missing is the basic idea of REST. For a solid explanation of how Rails handles control flow, try this answer.

But, basically, when you set resources :home in your routes it defines seven routes for your seven standard controller actions ( SHOW, INDEX, NEW / CREATE, EDIT / UPDATE, DESTROY ).

When you try to load a page in your browser you're sending a GET request. The NEW action accepts GET requests. The CREATE action only accepts POST requests (like submitting a form). So, after you POST your form to the CREATE action, you need to redirect to a page that accepts GET requests if you want to show the visitor something.

Alternatively it may be possible to override Rails default to allow CREATE to accept GET requests, but I would consider that to be a bad idea.

Probably the simplest thing you need to do is make sure your CREATE action in your controller looks like this:

def create
  (... do whatever processing of the params you want to do here ...)
  redirect_to home_path # OR whatever other path you want.

At the end of a controller action you can either render (default) or redirect. Redirect just jumps to another controller action and does whatever is in that action. Render typically shows a view with the same name as a controller action, but render has lots of options, see here.

To access params in the view the best thing to do is to assign them to an instance variable. IE:

def ... # any action that accepts GET requests
  @value = params[:value]

However, params will not persist after a redirect. So if you POST to one action and redirect to another (the normal convention), you'll need to either save the params to the DB, or save them to session.

In your case it looks like you should store them in session since they don't seem to be attached to a model.

Then in the next controller action you would check if there are certain variables in session and put them in instance variables to use in your view.


@value = session[:value] if session[:value]

I know this is a lot to absorb, but I hope this helps you wrap your mind around what's going on. One final suggestion, buy and read Beginning Rails 3. It's short, sweet, too the point, only takes a weekend to work through, and by the end you'll really understand the big picture of how rails works and your productivity and future learning will be quadrupled.

Good luck!

by anonymous   2017-08-20

Dan's answer above is correct, but as a simpler version of it, to create the association you're describing you need:

class Company < ActiveRecord::Base
  has_many :products
  has_many :users

class Product < ActiveRecord::Base
  belongs_to :company

class User < ActiveRecord::Base
  belongs_to :company

The Product and User tables need a column called company_id.

That's it! Now ActiveRecord will associate the objects intelligently on your behalf, and you can do things like:

@product =[:product]) =

The best way to understand how all these relationships work is to play with them in the console. Try things like:

Company.find_by_name('Acme').products.order('price DESC')

and so on...

Lastly, a thought: You would benefit immensely from reading an introductory book on Rails. I recommend 'Beginning Rails 3'. It's a fast read, you could work through it in a weekend, and it will make the big picture of how and WHY rails works the way it works very clear to you. The time spent reading the book will QUADRUPLE your productivity and the speed at which you learn more advanced stuff, because you'll be starting with a solid foundation and approaching problems "the rails way."

Your problem today was definitely a case of "you're doing it wrong", which doesn't mean there's anything wrong with your logic, just that you're making a simple problem much more difficult by trying to reinvent the wheel unnecessarily. Learning "the rails way" will make you much more productive, and will make the whole thing a lot more fun.