Understanding Scaffolding in Rails Better - ruby-on-rails

I've read the rails guides but there are some things that when I actually do it myself I still do not understand.
For example, how come when I visit my show view on localhost I get an error? Scaffolding created a show action in my controller that is empty and a view but still get an error message.
Similar thing happens with index.
Isn't the purpose of scaffolding to help you with all this? I assumed if I made a few posts that the index action would take me to an index of all the posts but it doesn't instead the post/ itself lists them all. What is the logic behind scaffolding doing this?
EDIT::::
This is the error message that I get:
ActiveRecord::RecordNotFound in ExperimentsController#show
Couldn't find Experiment with id=index
This happens when I visit http://localhost:3000/experiments/index

You are accessing the routes incorrectly.
To visit the index page : you need url http://localhost:3000/experiments
When you specify url : http://localhost:3000/experiments/index, Rails would match it to the route of show page(as shown below): /experiments/:id
If you read the error carefully:
ActiveRecord::RecordNotFound in ExperimentsController#show
Couldn't find Experiment with id=index
Rails mapped the url to show action and is trying to find an experiment with id=index which obviously does not exist and you get an error.
Run rake routes on command prompt and you'll see the routes created for resource experiment as follows:
/experiments index display a list of all experiments
GET /experiments/new new return an HTML form for creating a new experiment
POST /experiments create create a new experiment
GET /experiments/:id show display a specific experiment
GET /experiments/:id/edit edit returns an HTML form for editing an experiments
PATCH/PUT /experiments/:id update update a specific experiment
DELETE /experiments/:id destroy delete a specific experiment
You can access the specific routes with the paths shown above.
Replace :id with an existing experiment records id attribute value.
For eg:
To view an experiment with id 5
Visit http://localhost:3000/experiments/5
NOTE: I would highly recommend you to go through the Rails Routing Guide and get a better idea of how Routing works.

For a simple scaffolding task and assuming you followed the convention of naming, you should never get any errors, but even if you got an error my guess it will be a simple typo or pending-migrations type of error (something a quick googling should resolve)
Scaffolds are meant to give a push and increase Rapid Prototyping of your app but won't do the hole job for you.
I remember being confused just like you some time ago and i too was looking at the wrong direction trying to figure out what Scaffolding do while i should have looked on How Rails template system works which is the next step after learning Rails MVC basics.
Start from the guides, http://guides.rubyonrails.org/layouts_and_rendering.html#overview-how-the-pieces-fit-together and it will take some time to fully understand how rails works!

Related

How can I create a route and use a path to enter the first step in a mulistep form with the Wicked gem?

I have tried using the Wicked gem 3 different times over the past 8 years. Each time, I have given up for the same reason. I'm trying again, because if I understand it, I think it will be perfect for my use case.
My main problem is that I don't understand how to actually begin the wizard. With the example used in the gem, it is an after_registration event that already has an associated user object. That is not helpful, nor do I think that example would be helpful in the majority of use cases.
There is another example about building a Product in multiple steps. However, the author fails to adequately explain the routing. From https://github.com/zombocom/wicked/wiki/Building-Partial-Objects-Step-by-Step:
Since Wicked uses our :id parameter we will need to have a route that also includes :product_id for instance /products/:product_id/build/:id. This is one way to generate that route:
resources :products do
resources :build, controller: 'products/build'
end
This also means to get to the create action we don't have a product_id yet so we can either create this object in another controller and redirect to the wizard, or we can use a route with a placeholder product_id such as [POST] /products/building/build in order to hit this create action.
OK, I have no idea what the second part of the sentence means as far as placeholder product_id and that route name of /products/building/build. I spent 2 hours trying that and just moved on to a blank create form.
...we can either create this object in another controller and redirect to the wizard
That's what I'm trying to do upon successful save of the #product object.
redirect_to product_by_interchange_path(#product, :step1)
That doesn't work. raise InvalidStepError if the_step.nil? Says my step is nil. It's not.
redirect_to product_by_interchange_path(#product, step: :step1)
Same thing.
redirect_to product_by_interchange_path(:step1)
That's an exact mirror of the 8 year old example app. But of course #product isn't in a session variable like current_user is, so in this case the error is that there's no Product with an id of :step1.
Please help! I am missing something very, very basic here but I very much need to persist.
OK I have finally figured this out. Here's what I did:
First of all, I changed my controller back to a plain old ApplicationController and used the include include Wicked::Wizard. I don't know if that did anything, but the newer example was laid out like the old.
I was really screwed up by :id. I'm thinking :id is generally my object ID. I had a set_product private method in my controller, and it was failing. When I finally figured out that :id was the actual step itself, that led me to change my path in the redirect.
I changed the redirect from product_by_interchange_path(#product, :select_vehicle) to product_by_interchange_path(:select_vehicle, product_id: #product.id)
I got rid of my set_product. Just while I was trying to eliminate confusion.
I changed my finder calls in the wizard to use :product_id instead of :id.
It works now. I still don't understand how I could have stubbed out a route with a placeholder product_id, that's still a mystery. But this is fine and it works.

Rails 4 routing of partial tacks on to existing path

I am new to writing rails applications. I am using Rails 4.2.0 with Ruby 2.0.0p598.
I have modified the cascading select implementation found here and used it to create new Products (has model and main controller) linked to Productgroups and Productsubgroups (both have their models, but no controllers) as the cascade levels. The implementation employs some javascript which upon a change to the first dropdown select, the second dropdown is cleared of data, and then an AJAX call is made to a specific URL to update the tags for the productsubgroups dropdown using a partial (_productsubgroup.html.erb).
To do this, the following route set up in routes.rb
get '/update_productsubgroups' => 'products#update_productsubgroups'
so that i can map to the appropriate controller and action. This is all quite fine. I can see the AJAX request in the development.log as where it is querying the database for productgroup #2 (ignore the trailing "&_1422575676984"):
Started GET "/products/update_productsubgroups?productgroup_id=2&_=1422575676984"
The problem, occurs when I use the same content from new.html.erb within the context of editing a product in edit.html.erb. Based on the fact that the routes.rb uses the "resouces :products" directive, I end up with a url for editing products in the form /product/:id/edit (e.g. /product/2/edit to edit the product with ID 2). When I try to use my cascading dropdowns, everytime I make a change to the first selection, I don't get a change in the second dropdown. I can see the request going to the development.log file as:
Started GET "/products/1/update_productsubgroups?productgroup_id=2&_=1422578544393"
and the error that comes up immediately after the request is:
ActionController::RoutingError (No route matches [GET] "/products/1/update_productsubgroups"):
Q1 - Why does the partial just tack on to the existing URL rather than simply make a pure request to /products/update_productsubgroups as is the case when I create a product from the product controller's 'new' action?
Q2 - Is there any way for me to create a rule in the routes.rb to map things correctly?
Q3 - When I try to create a new route as
get '/products/:id/update_productsubgroups', as 'products#update_productsubgroups'
I get an error in the webserver log as:
ArgumentError ('products/:id' is not a supported controller name
I have dug around and I am not certain how to interpret this. Can anyone help explain this so that the last couple of hours can prove a useful learning experience? Unfortunately, most pages either discuss routing for Rails 3 or just refer to the 'Routing from the outside in' page and that seems to confuse me even more because I'm specifying things as expected, namely :controller/:id/:action.
DOH!
I had a relative path specified for my AJAX call! I looked everywhere except the coffeescript file.
$.ajax 'update_productsubgroups',
should be
$.ajax '/update_productsubgroups',

very beginner RoR routing (new dynamic URL)

I have worked through the "getting started" Rails tutorial and am trying to understand routing better so that I can expand the sample project. (I've read this routing guide but didn't fully understand it - I think what I'm trying to do is simpler than what's covered there.)
Taking the sample blog project as a base, I am trying to add the ability to view all entries by a given author. I've modified the original project so that "author" is a field in the database and is accessible in the index (along with "title" and "text") (I can call #book.author), and I've figured out a (probably very hacky and incorrect) way of listing all authors and subjects on a separate page, but I have been unable to set up a way of filtering the articles by author.
In the same way that the "show" link in the sample project passes the article id to the controller and gives a view of the article with that id, I want to be able to have a similar link for each author which would pass the contents of the :author field to the controller to get all articles that share that author.
(I went down a really tangled rabbit hole manually setting up a separate controller for "authors" and trying to create a gets "authors/:author" line in the routes.rb file. Creating the controller and a view where I could list the authors themselves worked, but any attempt to set up a route with :author (or :id) as a parameter (so that each author would have a page listing his articles) didn't work - not sure why given that it looked, to me, the same as what was shown in the routing guide (above). But I'm pretty sure this is not the way to do this, so I'm starting over and trying to do it right.)
(I hope that this question isn't too general. I'm assuming that the answer here is very simple - I just haven't been able to figure it out from the obvious documentation or tutorials I've seen.)
It's usually a simple nested resources...
resources :authors do
resources :articles
end
This gives you a route authors/:author_id/articles (named as author_articles_path(#author))
In your articles index controller you would do..
def index
#author = Author.find(param[:author_id])
#articles = #author.articles
end
hope this helps.

Rails param for show page

I've used params in a URL for the index page successfully. But, I'm not getting the same success with the show page.
This is what I'm trying to use:
def show
#workorder = Workorder.find(params[:id])
#workorder = Workorders.where("wonum = #{params[:wonum]}") if params[:wonum].present?
Then I'm trying those URLs:
http://localhost:3000/workorders/?wonum='14-21291'
http://localhost:3000/workorder?wonum='14-21291'
Thanks for the help!
UPDATE 1
Rake Routes:
UPDATE2
What I would really like is this url to work:
http://localhost:3000/workorder?wonum='14-21263'
Could I add a route to the workorder show function?
You are almost there, you just need some minor changes and you'll get what you need.
It's important to understand that rails expects route ids to corrospond to database ids like the following:
http://localhost:3000/workorder/32'
This will save 32 in params[:id]
This is the default behavior and you will see this in all the rails beginner examples.
You will run into problems because you are trying to find Work orders by a different field, not id. So you need to change the code in your workorders controller.
Try this:
def show
#workorder = Workorders.where(:wonum, params[:wonum]).first if params[:wonum].present?
#workorder = Workorder.find(params[:id]) if #workorder.nil?
The major differences are how I call the where method (this way where add security for you) and trying to find a workorder from the :wonum parameter before trying to find it using the id. I suspect in your attempt, you were getting a record not found, or routing exception because you didn't pass in an id at all in your example url.
With an id:
http://localhost:3000/workorder?333wonum='14-21263'
I suggest looking at the sql generated in your rails server window to see what is going on.
You should look at this gem for a cleaner, off the shelf solution to what you're trying to do -> https://github.com/norman/friendly_id/

Beginner with Rails 3.1 and "static" pages

I just started deploying a Rails website. In fact, I started programming on Rails 2 days ago.
I've created a new project, added some gems, etc. Everything is working properly, and I have some basic knowledge on how all works.
The thing is that what I want to create is a simple website with some sections (let's say, News, Contact, About, Products...). All this content is kinda static.
But I came in a problem. I don't really know what to do in order to create them. What I want, for example, is something like mypage.com/products/fashionableproduct, mypage.com/about, etc, or even mypage.com/page/products.
I thought about creating a Controller, then an action for each page... afterwards, I came up with other solution: scaffolding. Creating a resource called page, that has a title, etc...
I'm really a beginner on this topic, and I would like to hear your helpful voice.
Thanks!
Check out https://github.com/thoughtbot/high_voltage for static pages for Rails.
And check out http://railscasts.com/episodes/30-pretty-page-title for setting page titles.
The paths to your files are determined by your routes. The configuration file for routes is located at config/routes.rb. You can match a URL path, and then point to a given resource. More information about routes here: http://guides.rubyonrails.org/routing.html
If you generate a controller, you can process any dynamic data and then pass this data to these "kinda static" pages. Here is an example configuration that would match the path "mypage.com/about" and display the appropriate page:
# config/routes.rb
match "/about" => "example_controller#about"
# app/controllers/example_controller.rb
class ExampleController < ApplicationController
def about
# calculations
end
end
# app/views/example/about.html.erb
<!-- This is your HTML page -->
I think the title of your post might be a bit misleading. I have the feeling you don't want static pages but some database stored content. Just like Ben Simpson tells you to do, create a normal pages controller and make it work.
In the end you might want to customize some routes to get them to be exactly the way you want as in your examples.
Since you just started the app, I strongly recommend you start over and make a new app with Rails 3.1 which is the most current version and learn how to do the basics through http://guides.rubyonrails.org/ and a few other sources such as http://railscasts.com.
You will then learn Rails the right way from the beginning. Good luck and have fun in the process.

Resources