2016-04-23 2 views
0

Я хотел бы условно отобразить/скрыть некоторые элементы в одном из моих представлений в зависимости от того, изменили ли атрибуты @project.update или нет.экземпляры экземпляров не помечены как измененные после успешного обновления атрибута

Я пытаюсь понять, почему мои экземпляры модели не помечены как измененные после успешного обновления атрибута.

похоже, что ActiveModel::Dirty не соответствует действительности, изменив атрибуты моей модели или, скорее всего, я не использую ее должным образом.

Вот аннотированный журнал запроса PATCH, который я делаю для своего действия ProjectController#update. В нем вы увидите, что атрибуты изменяются, но экземпляр модели не отражает его. Для чего это стоит, контроллер был сгенерирован с помощью эстакады Rails. Нет ничего необычного.

# 
# FORM SUBMITTED FROM BROWSER WITH A CHANGE TO THE ATTRIBUTE NAMED "title" 
# 
Started PATCH "/projects/2" for 127.0.0.1 at 2016-04-23 15:47:38 -0700 
Processing by ProjectsController#update as HTML 
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"0JH/fEKx+Qk6mOY+eVTteKQUKrZUVXroKzMxuztrTzE/voI+PtzmQnJLGVM5bgdmzJyHDpAon3dzcvvjJ3yEtQ==", "project"=>{"title"=>"changed"}, "commit"=>"Update Project", "id"=>"2"} 
    Project Load (0.1ms) SELECT "projects".* FROM "projects" WHERE "projects"."id" = ? LIMIT ? [["id", 2], ["LIMIT", 1]] 

# 
# DEBUGGER KICKS IN BEFORE THE UPDATE HAS HAPPENED 
# 
[40, 49] in app/controllers/projects_controller.rb 
    40: 
    41: # PATCH/PUT /projects/1 
    42: # PATCH/PUT /projects/1.json 
    43: def update 
    44:  byebug 
=> 45:  respond_to do |format| 
    46:  if @project.update(project_params) 
    47:   format.html { redirect_to @project, notice: 'Project was successfully updated.' } 
    48:   format.json { render :show, status: :ok, location: @project } 
    49:  else 

# 
# PROJECT TITLE IS STILL UNMOLESTED 
# 
(byebug) @project 
<Project id: 2, title: "ORIGINAL_TITLE", created_at: "2016-04-23 22:47:30", updated_at: "2016-04-23 22:47:30"> 
# PROVE PARAMS CONTAIN A CHANGED ATTRIBUTE 
(byebug) project_params 
<ActionController::Parameters {"title"=>"changed"} permitted: true> 

# 
# TRIGGER UPDATE AND PERSIST NEW TITLE 
# 
(byebug) @project.update(project_params) 
    (0.2ms) begin transaction 
    SQL (0.9ms) UPDATE "projects" SET "title" = ?, "updated_at" = ? WHERE "projects"."id" = ? [["title", "changed"], ["updated_at", 2016-04-23 22:48:13 UTC], ["id", 2]] 
    (3.5ms) commit transaction 
true 

# 
# WAT? 
# 
(byebug) @project.changes 
{} 
(byebug) @project.changed? 
false 
(bye bug) 

Вот мой ProjectsController#update действия (стандартный Rails леска):

# app/controllers/projects_controller.rb 

    # PATCH/PUT /projects/1 
    # PATCH/PUT /projects/1.json 
    def update 
    byebug 
    respond_to do |format| 
     if @project.update(project_params) 
     format.html { redirect_to @project, notice: 'Project was successfully updated.' } 
     format.json { render :show, status: :ok, location: @project } 
     else 
     format.html { render :edit } 
     format.json { render json: @project.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

Соответствующая форма вида (также из сгенерированных строительных лесов):

# app/views/projects/_form.html.erb 

<%= form_for(project) do |f| %> 
    <% if project.errors.any? %> 
    <div id="error_explanation"> 
     <h2><%= pluralize(project.errors.count, "error") %> prohibited this project from being saved:</h2> 

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

    <div class="field"> 
    <%= f.label :title %> 
    <%= f.text_field :title %> 
    </div> 

    <div class="actions"> 
    <%= f.submit %> 
    </div> 
<% end %> 
+0

Можете ли вы отправить свой метод 'update' и' form' – 7urkm3n

+0

Можете ли вы рассказать мне, что именно вы пытаетесь достичь, сделав это? это как вы хотите что-то сделать после обновления, если произошли какие-либо изменения? – Alfie

+0

Я добавил дополнительную информацию, отвечая на оба запроса. –

ответ

0

Похоже, вы пытаетесь добиться чего-либо, если бы произошли какие-либо изменения, внесенные во время обновления.

Если это так, то вы могли бы сделать что-то вроде этого:

Используйте after_save или after_update обратного вызова по мере необходимости для модели и внутри обратного вызова, если вы проверяете self.changes или self.changed? вы бы получить ожидаемые результаты.

+0

Извините, мой плохой. Позвольте мне снова проверить – Alfie

+0

вы можете попробовать использовать 'update_attributes' вместо' update' – Alfie

+0

@BillyBlobSnortin. Вы снова правы. См. Мой обновленный ответ для решения. – Alfie

Смежные вопросы