Agile Web Development with Rails 6 and later software updated to Rails 7:

@rubys

Title: Name of book: text: Agile Web Development Rails6, p. 183, Iteration G1: Capturing an Order.

I started working on a web dev draft using Rails 6 and before Iteration G1: “Capturing an Order” the software was updated to Rails 7.0.4.3 dev and Ruby 3.1.3.

Although “your Cart” was rendered on page 183, the “Please Enter Your Details” form was not rendered.

Question: Is the switch to Rails 7 the reason for form rendering not working?
Does anyone know what it could be? Any thoughts to solve this issue?

Thank you,

Tag; “Please Enter Your Details” Form - Cart - Iteration G1

Are you using the exact sample code included with the book, or is this your code you are typing as you are following along? If the later, can you post a repo of your app in progress? I can take a look.

Hi, the partial _form.html.erb as follows: <%= form_with(model: order, local: true) do |form| %>
<% if order.errors.any? %>


<%= pluralize(order.errors.count, “error”) %> prohibited this order from being saved:

  <ul>
    <% order.errors.full_messages.each do |message| %>
      <li><%= message %></li>
    <% end %>
  </ul>
</div>

<% end %>

<%= form.label :name %> <%= form.text_field :name, size: 40 %>
<%= form.label :address %> <%= form.text_area :address, rows: 3, cols: 40 %>
<%= form.label :email %> <%= form.email_field :email, size: 40 %>
<%= form.label :pay_type %> <%= form.select :pay_type, Order.pay_types.keys, prompt: 'Select a payment method' %>
<%= form.submit 'Place Order' %>
<% end %>

The application.scss file as follows: /*

  • This is a manifest file that’ll be compiled into application.css, which will include all the files
  • listed below.
  • Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin’s
  • vendor/assets/stylesheets directory can be referenced here using a relative path.
  • You’re free to add application-wide styles to this file and they’ll appear at the bottom of the
  • compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
  • files in this directory. Styles in this file should be added after the last require_* statement.
  • It is generally better to create a new file per style scope.

*= require_tree .
*= require_self
*/

body {
margin : 0;
padding : 0;
}
header.main {
text-align : center; // center on mobile
@media (min-width: 30em) {
text-align : left; // left align on desktop
}
background : #ecff8d;
margin : 0;
h1 {
display : none;
}
}

.cart, #cart {
article {
h2 {
margin-top: 0;
}
background: white;
border-radius: 0.5em;
margin: 1em;
padding: 1.414em;
@media (min-width: 30em) {
margin: 0; // desktop doesn’t need this margin
}
}
}

.notice, #notice {
background : #ffb;
border-radius : 0.5em;
border : solid 0.177em #882;
color : #882;
font-weight : bold;
margin-bottom : 1em;
padding : 1em 1.414em;
text-align : center;
}

.content {
margin : 0;
padding : 0;

display : flex;

flex-direction : column; //mobile is horizontally laid out
-webkit-box-orient : vertical;

@media (min-width : 30em) {
    flex-direction : row;  //desktop is vertically laid out
    -webkit-box-orient : horizontal;    
}

nav {
    padding-bottom : 1em;
    background : #5e9922;
    text-align : center; // mobile has centered nav
    @media (min-width : 30em) {
        text-align : left ; // desktop nav is left-align
        padding: 1em; // and needs more padding
    }
    ul {
        list-style : none;
        margin : 0;
        padding : 0;
        @media (min-width : 30em) {
            padding-right : 1em; // give desktop some extra space
        }
        li {
            margin : 0;
            padding : 0.5em;
            text-transform : uppercase;
            letter-spacing : 0.354em;
            a {
                color : #bfb;
                text-decoration : none;
            }
            a: hover {
                background : none;
                color : white;
            }
        }
    }
}

main {
    padding : 0.5em;
}

}

.depot_form {
padding: 0 1em;
h1 {
font-size: 1.99em;
line-height: 1.41em;
margin-bottom: 0.5em;
padding: 0;
}
.field, .actions {
margin-bottom: 0.5em;
padding: 0;
}
.actions {
text-align: right;
padding: 1em 0;
}
input, textarea, select, option {
border: solid thin #888;
box-sizing: border-box;
font-size: 1em;
padding: 0.5em;
width: 100%;
}
label {
padding: 0.5em 0;
}
input[type=“submit”] {
background-color: #bfb;
border-radius: 0.354em;
border: solid thin #888;
color: black;
font-size: 1.41em;
font-weight: bold;
padding: 0.354em 1em;
}
input[type=“submit”]:hover {
background-color: #9d9;
}
// Also, clean up the error styling
#error_explanation {
background-color: white;
border-radius: 1em;
border: solid thin red;
margin-bottom: 0.5em;
padding: 0.5em;
width: 100%;
}
h2 {
background: none;
color: red;
font-size: 1.41em;
line-height: 1.41em;
padding: 1em;
}
ul {
margin-top: 0;
li {
color: red;
font-size: 1em;
}
}
}
.field_with_errors {
background: none;
color: red;
width: 100%;
label {
font-weight: bold;
}
label::before {
content: "! ";
}
input,textarea {
background: pink;
}

}
I’m using the exact sample code as described in the book. I’d appreciate some input.
Thank you in advance.

Can you use the editor to format this as code or, more ideally, post to GitHub a repo of your entire app? I can’t debug this in this format as the forum software has totally mangled what you pasted.

I think I’ll post it to GitHub and let you know. Thank you

I’m posting to GitHub a repo of my entire app. I was wondering whether I can add your GitHub username or email address?

Can you make it public and post a link? If not, my GH username is the same as it is here

The repo is public and you were added as a collaborator.
Thank you in advance,

Cool. Maybe I’m missing something but it doesn’t look like the view required is in the app. On page 180, the book says to create app/views/orders/new.html.erb This includes code to render the partial “form”, which would be in app/views/orders/_form.html.erb That’s the form that has the “Please Enter Your Details” stuff in it that you are missing.

I don’t see any of that in the app - I also don’t see anywhere else it might be.

My bad, I saw that some files weren’t added to GitHub properly. The following GitHub update was done: $ git add . $ git commit -am ‘code snippet removed from app/views/orders/new.html.erb’ to reflect code on page 180. $ git push I think you should be able to see the files now. Let me know

Is it now working for you? At a glance, the code looks correct.

If it’s not working, some things to look at:

  • What HTML is being produced? Do you see “Please Enter Your Details” but no form or do you see nothing?
  • Check the output of bin/rails server for error messages
  • Are you sure you are rendering the new action for orders? The output from bin/rails server should show you what controller and action is being triggered

If you still can’t figure it out, you will need to find a way to debug what is happening. To do that with puts statements, you can add them anywhere in ruby code:

def new
  puts "IN NEW!"
  @order = Order.new
end

or in ERB:

<% puts "HERE" %>

or, again in ERB, put markup the shows up on the page:

--<h1>HERE</h1>--

You may also have success with pry, but I have never used it so not sure the best way to do that.

  • I just see the cart rendered, but no form next to it like you see on p. 183
  • The bin/rails server output indicates the following (but no mention of form rendering):
    Started GET “/carts/39” for ::1 at 2023-08-23 11:06:01 -0400
    Processing by CartsController#show as HTML
    Parameters: {“id”=>“39”}
    Cart Load (0.7ms) SELECT “carts”.* FROM “carts” WHERE “carts”.“id” = ? LIMIT
    ? [[“id”, 39], [“LIMIT”, 1]]
    ↳ app/controllers/carts_controller.rb:14:in show' LineItem Load (0.7ms) SELECT "line_items".* FROM "line_items" WHERE "line_ite ms"."cart_id" = ? [["cart_id", 39]] ↳ app/controllers/carts_controller.rb:16:in show’
    Rendering layout layouts/application.html.erb
    Rendering carts/show.html.erb within layouts/application
    Rendered carts/show.html.erb within layouts/application (Duration: 2.1ms | All
    ocations: 122)
    Product Load (0.6ms) SELECT “products”.* FROM “products” WHERE “products”."id
    " = ? LIMIT ? [[“id”, 3], [“LIMIT”, 1]]
    ↳ app/views/line_items/_line_item.html.erb:19
    Product Load (0.5ms) SELECT “products”.* FROM “products” WHERE “products”."id
    " = ? LIMIT ? [[“id”, 4], [“LIMIT”, 1]]
    ↳ app/views/line_items/_line_item.html.erb:19
    Rendered collection of line_items/_line_item.html.erb [2 times] (Duration: 14.
    9ms | Allocations: 2109)
    Rendered carts/_cart.html.erb (Duration: 25.0ms | Allocations: 3110)
    Rendered layout layouts/application.html.erb (Duration: 67.6ms | Allocations:

Completed 200 OK in 133ms (Views: 92.7ms | ActiveRecord: 4.3ms | Allocations: 91
23)

  • The new.html.erb for orders as follows:

Please Enter Your Details

<%= render “form”, order: @order %>

It looks like everything is place, however, I think there is a need to debug as you indicated.

The log output you pasted is for the cart show method, not order new.

One thing you can put in your app/views/layouts/application.html.erb that can help debug is something like this:

<h1>!! controller: <%= controller_name %></h1>
<h1>!! action: <%= action_name %></h1>

controller_name and action_name will tell you what controller and action was used to render the page. That way you can start trying to figure out where something is wrong, e.g. perhaps there is a link somewhere going to the wrong controller/action?

The code was switched to cart/show method which is correct because when you refresh the page, you can see “Please enter Your Details” and the Update Cart button.
On the other hand, the code was misplaced in the book to orders/new on p.180, right?

Could be I’m confused as to what you are doing. The section titled “Creating the Order Capture Form” that starts on page 177 is all about creating the order/new view. The code on page 177 calls out the addition of a button that triggers the orders/new action. When that button is clicked it should trigger the new action on the orders controller. I wonder if this is the issue.

Looking at your repo, the link doesn’t do that: https://github.com/CharlieCarrJac/railsdepot1/blob/7bc1b872754790bae9f4b629b6377eb6c45fbcc1/app/views/carts/_cart.html.erb#L25

It’s going to the show method of the cart controller:

<%=  button_to "Continue to Secure Checkout", cart, method: :get, class:"checkout-cart" %>

It should do this (copied from the book):

<%= button_to 'Checkout', 
              new_order_path, 
              method: :get, 
              class: "checkout"%>

Sorry, I just updated add & push GitHub

Still shows a button to the cat show method to me. Looks like you removed the orders new view. That’s not the way to solve this. You are probably getting different errors now because the render "form" from carts/show.html.erb is going to look for carts/_form.html.erb

Is there a reason you aren’t following the books’ recommendation to use the order/new resource? Semantically what is happening is that when you click checkout, you creating a new order, so having that happen as the new action on OrdersController (which will then submit to create) follows Rails’ conventions (and somewhat follows RESTful conventions they are based on)

The issue starts when I click the “Continue to Secure Checkout” button. The page displays the cart but not the “Please enter your details” form

I think I’m following the books’ recommendation to use the order/new resource; however, I was wondering whether this code snippet should be in both files: orders/new and carts/show?

I would change your code to match what’s in the book. IN this case, you need to keep the views/orders/new.html.erb template and have the button in app/views/_cart.html.erb configured to trigger the new_order_path.

What you have in app/views/_cart.html.erb is using the cart show path:

<%= button_to "Continue to Secure Checkout", cart, method: :get %>

The second argument is a Cart and the third argument (method: :get) says to use an HTTP GET. Rails combines these two pieces of information and will trigger /carts/«card.id», which will call CartsController’s show method, and params[:id] will be the value of card.id

The book says to do this:

<%= button_to 'Checkout',  new_order_path,  method: :get %>

This is a bit of a weird Rails thing, but in this case, the second argument is not an Active Record, but is a string returned by the method new_order_parth. That method returns /orders/new.

If you do bin/rails routes on the command line, you will see a bunch of stuff around orders. You should see a line that indicates the new action on the OrdersController. It may be confusing because Rails sometimes will say orders in place of OrdersController.

But, at any rate, clicking the button above (that goes to new_order_path) will trigger the OrdersController’s new method. And that will render the view in app/views/orders/new.html.erb. That view calls render 'form' which will render app/views/orders/_form.html.erb and insert that into the view.

LMK if this makes sense - Rails has a lot of implicit/conventional behavior that can get confusing, especially because sometimes if you don’t get it 100% right, Rails won’t give you an error but just acts weird.