简体   繁体   中英

How does Rails know which variable to take

Beginner in Rails here by following tutorial by mackenziechild.me. For example, I have created a PostController with lots of method. However, what confuses me is they seem to have the same variable @post. In this case, how do the program actually knows which correct variable it needs to get? Don't they will get confused when the application is running?

class PostsController < ApplicationController
    def index
        @posts = Post.all.order('created_at DESC')
    end

    def new
        @post = Post.new        
    end 

    def create
        @post = Post.new(post_params)

        if @post.save
            redirect_to @post
        else
            render 'new'
        end     
    end

    def show
        @post = Post.find(params[:id])
    end 

    private

    def post_params
        params.require(:post).permit(:title, :body)
    end     
end

In rails each action like index, new, show etc which is a get method has their corresponding views in the corresponding folder named as the controller name.

So when a action is called then their particular view is called.

Eg:-

def index
    @posts = Post.all.order('created_at DESC')
end

Their should be a view as index.html.erb in the folder app/views/posts/ and in that view the instance variable @posts will be accessible.

In this line Post.all.order('created_at DESC') , Post model query the database and fetch all the record from the table as posts and also sort the record in descending order of created _at column.

Post model is inherited from ActiveRecord::Base , due this it can map the posts table in the database.

def show
    @post = Post.find(params[:id])
end 

In the above show method it is querying only one record whose id is in params[:id] .

Instance variables are accessible in the views so in @post = Post.find(params[:id]) @post can be used in its corresponding view as show.html.erb in app/views/posts/

Ikanyu, the @post variable is an instance variable ie its scope is limited to the method it is defined in. So the @post variable defined in new method is different from the one defined in show and the hence these different variables are accessed in the views without any issue.

For more info as to how these variables are passed into view refer to this link:

How are Rails instance variables passed to views?

I have created a PostController with lots of method. However, what confuses me is they seem to have the same variable @post. In this case, how do the program actually knows which correct variable it needs to get? Don't they will get confused when the application is running?

When your browser requests a page, the request is routed to ONE of the methods you defined. That method executes, and that method sets the value of @post. After the response is sent to the browser, rails destroys all the variables that were created.

but we have Post.new, Post.new(post_params), Post.find(params[:id]) I came from a Java background. so this is quite confusing me. They area all being assigned to the same @post

In Java, you can certainly assign three things to the same variable:

int x = 1;
x = 2;
x = 3;
System.out.println(x);  #=>3

And, if you have a class named Post you can also assign three different Post objects to the same variable:

    Post p = new Post("hello");
    System.out.println(p.getText());
    p = new Post("world");
    System.out.println(p.getText());
    p = new Post("goodbye");
    System.out.println(p.getText());  #=>goodbye

Each of: Post.new , Post.new(post_params) , and Post.find(params[:id]) returns a Post object; additionally they are being assigned to the same variable, so why are you confused by that coming from a Java background ?

However, you should also note that Rails uses a language called ruby under the hood, and in ruby variables do not have types, and they do not have to be declared. So, in ruby you can assign different types to the same variable:

some_var = "hello"  #String
some_var = 10  #Integer
some_var = [1, 2, 3]  #Array
some_var = {a: 1, b: 2}  #Hash

If you said that you were confused by something like that, it would make more sense. Yet, what's there to be confused about by even that? There are two simple rules:

  1. Variable names do not have types.
  2. As a result, you do not have to declare variables.

Earlier, I said this:

When your browser requests a page, the request is routed to ONE of the methods you defined. That method executes, and that method sets the value of @post. After the response is sent to the browser, rails destroys all the variables that were created.

Internally, the way that works is:

  1. When a url is routed to a certain controller, rails creates an instance of that controller class:

    obj = PostsController.new

  2. Rails uses the controller instance to call one of the methods defined in the controller class(the method is determined by the routing):

    obj.show

(Just like in Java, there are ways to call a method when you have the name of the method as a String--and it's much easier in ruby.)

  1. The method executes.

  2. After the response is sent to the browser, rails destroys the controller instance:

    obj = nil

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