简体   繁体   中英

Ruby on Rails. Understanding loops

I'm definitely getting somewhere with RoR. Just want to clarify some things regarding loops.

I've created an 'inputs' controller that contains methods to let a user create, read, update and delete database entries.

I also have an 'inputs' view that renders the html frontend. In the view is the following loop:

<table>
<% @inputs.each do |input| %>
  <tr>
   <td><%= input.title %></td>
   <td><%= input.content %></td>
   <td><%= link_to 'Show', input %></td>
   <td><%= link_to 'Edit', edit_input_path(input) %></td>
   <td><%= link_to 'Destroy', input, method: :delete, data: { confirm: 'Are you sure?' } %>  
</td>
  </tr>
<% end %>
</table>

I understand how loops work conceptually, but I'm a bit lost on this.

I think the @inputs 'points the code' (better way of expressing that, please?) towards the inputs controller where the the methods used by the loop live.

Inside the inputs controller there are indeed methods such as 'edit', 'create', 'show' and 'destroy'.

But there are not 'title' or 'content' methods in the controller! Where do they come from?

And, to be honest, I do not understand

<% @inputs.each do |input| %>

very well.

This is me trying to understand:

@inputs = go to the inputs controller

.each = call an each method on the inputs controller. (Where is this each method defined? What does it even mean, calling each on a controller?)

do | input | = Whatever the heck calling .each on a controller does, it generates an object called 'input'.

Now, the object 'input' does indeed contain methods such as title and content, but where are these methods coming from?? They are literally nowhere inside the controller!

Anyway, thanks a lot.

When you use @inputs inside your view template as you've shown in the code above, the view template is using the instance variable @inputs that has been defined inside the controller action that rendered the view template.

In other words, to use an example, let's say your InputsController has a method called index . In your view folder, you have a corresponding view template named index.html.erb .

# Inside app/controllers/inputs_controller.rb
def index
  @inputs = Input.all
end

# Inside app/views/inputs/index.html.erb
<table>
<% @inputs.each do |input| %>
  <tr>
   <td><%= input.title %></td>
   <td><%= input.content %></td>
   <td><%= link_to 'Show', input %></td>
   <td><%= link_to 'Edit', edit_input_path(input) %></td>
   <td><%= link_to 'Destroy', input, method: :delete, data: { confirm: 'Are you sure?' } %>  
</td>
  </tr>
<% end %>
</table>

When the index method is called, Rails will, by default, look for a view template of the same name as the method being called; that is to say, it will search for a view template called index.html.erb .

Using the example I've given here, @inputs used inside the view template has been instantiated from the index action that was called from the controller.

Furthermore, as you can see from the instantiation of the @inputs variable:

@inputs = Input.all

@inputs is a variable that references a collection of objects from your database. In other words, inside the loop in your view template, at this section:

<% @inputs.each do |input| %>

each |input| is a reference to one of the objects contained inside the @inputs collection, and in turn, each of these objects corresponds to a database object (ie the Input model). That is why each input has attributes called title and content , because these were probably defined in your database migration as columns of the Input table.

Given @inputs being a collection of items (an array, for instance),

.each do does iterate on each item.

|input| says "put each item in the variable input so I can use it in the block do .. end.

@items is a variable set by the controller. If your is empty (like when you use scaffolding), just know ruby on rails does the work for you, as if you had in your controller:

def index
  @inputs = Input.all
end

@inputs is an instance variable which is instantiated with collection of some objects in controller. Being an instance variable, it is present in your associated view.

#each is a Ruby iterator which iterates over an array, and pipes an element one at a time, in |input| here. So, at each iteration, |input| becomes a next object from the @inputs array.

Now, keep in mind that input is an object . An object in Rails have several attributes. Here title , content are model attributes/fields which may/may not contain some value. A User model, for instance, can contain attributes like - name , email_address .

new , create , edit , update , index , show , destroy are the RESTful routes in the controllers, each performing an action and each has an associated view.

link_to is a ActionView helper to insert a link in your template.
link_to Show , input takes you to the show action of your controller.
link_to 'Edit', edit_input_path(input) takes you to the edit action of your controller.
And so on.. These are the actions/methods of your controllers.

Hope it helps. :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM