Проблема сеанса в rails?

#ruby-on-rails #session

#ruby-on-rails #сеанс

Вопрос:

Предположим, это мой пользовательский контроллер:-

 class UsersController < ApplicationController
 def show
  @user = session[:user]
 end

 def prepare
  session[:user]= User.find(:first)
  redirect_to :action => 'show'
end

def update
 @user = session[:user]
 @user.name = 'rai'
redirect_to :action => 'show'
end
end
  

Просмотр для show.html.erb

 <%= @user.name %>
Show page
<%= link_to 'Update', :action=> 'update' %>
  

Теперь объясняю проблему:—
Предположим, что пользователь впервые открывает браузер с

  http://localhost:3000/users/prepare
  

o / p будет:—

  Mohit Show page Update  // supposing user table has values mohit as name
  

Теперь, когда он нажмет на обновить, он получит в качестве вывода примерно следующее:—

   rai Show page Update
  

Но этого не должно произойти, потому что

во-первых, когда выполняется действие подготовки, где значение извлекается из базы данных и ее мохита. и затем он перенаправляется на show ie, отображающий значения из сеанса. ie mohit

Теперь, когда пользователь нажимает на обновление, он перенаправляется на обновление, когда значение из сеанса сохраняется в экземпляре пользователя, и атрибут name этого экземпляра пользователя был изменен на rai. и, наконец, перенаправлен на страницу показа.

Теперь на этой странице, когда отображается имя пользователя, отображается rai .. вот ВОПРОС, почему?? потому что в сеансе должно храниться то же значение mohit, потому что мы не внесли никаких изменений в сеанс..

Ответ №1:

Когда вы делаете

 @user = session[:user]
  

@user переменной присваивается ссылка на объект session[:user] , а не на его копию.
Итак, когда вы изменяете @user , session[:user] также изменяется, поскольку они, по сути, являются одним и тем же объектом.

Комментарии:

1. Да, вот что происходит.. я могу понять, но я не в состоянии понять, почему это происходит ..!!!

2. В ruby переменные содержат ссылки, а не значения. Итак, когда вы назначаете, вы копируете ссылки. ruby-doc.org/docs/Newcomers/ruby.html#objects

Ответ №2:

Я не уверен, но я думаю, что это что-то с хэшами и классами и с их копированием. Итак, когда вы делаете:

 @user = session[:user]
  

Вы не создаете копию object, но это что-то вроде ссылки в C , оба @user и session[:user] ссылаются на один и тот же объект, поэтому, когда вы изменяете один, вы получаете оба изменения.

Пример из консоли:

 a = {}
a[:user] = User.first
a[:user].firstname           # => "Mohit"
b = a[:user]
b.firstname = 'rai'
a[:user].firstname           # => 'rai'
a[:user] = User.first
a[:user].firstname           # => 'Mohit'
  

Комментарии:

1. Да, вот что происходит.. я могу понять, но я не в состоянии понять, почему это происходит ..!!!

2. @piemesons: при назначении @user = session[:user] вы не копируете пользовательский объект. Вы копируете «указатель» на этот объект. Итак, например, если у вас есть друг по имени «Боб», и вы даете ему 100 долларов, то у него есть 100 долларов :). Теперь, если вы назовете его «Foo» (это тот же человек, но с другим именем) и дадите ему еще 100 долларов, у него теперь будет 200 долларов, а не 100 долларов. Это очень похоже на то, что произошло с вашим объектом сеанса.

3. В этом примере консоли вы можете вызвать a[:user].object_id и b.object_id , и это то же самое. Это означает, что оба a[:user] и b ссылаются на один и тот же объект.