简体   繁体   中英

Rails: How can I load new values into a form on edit but only persist them on save?

I've got a Rails 4 app with a service that loads required objects on a new/edit document action, and this is a method from it:

def template_variables
  if @document.template_variables.any?
    TemplateVariable.where(id: document_vars).each do |v|
      next unless User.method_defined?(v.name.to_sym)
      v.update_attribute(:text, @user.send(v.name.to_sym)) # problem line, persists the change when i don't want to
      v.text = @user.send(v.name.to_sym) # also a problem, doesn't update the value in the form at all
    end
  else
    TemplateVariable.where(id: master_vars)
  end
end

I need a solution for the two problem lines (they are just two things I've thought of, and they aren't supposed to both be there but I've included both for the sake of my problem).

The first updates and persists the change to the model which is behaviour I don't want. The second line doesn't do anything, where logically it seems like it should replace whatever text was in that variable in the form with @user.send(v.name.to_sym) . It appears to do nothing.

Is there are solution to this problem that I'm unaware of?

Bonus points if there's a way to list the fields with new values to display in a flash[:notice] .

Update now with relevant form code.

<%= v.input :text, as: :string, input_html: { value: v.object.text } %>

Setting the value/vs not setting it doesn't change anything either.

If you've got an instance variable that you're passing from your controller, you can set (but not save) values on that variable which will be available in the view.

For example, you can set the first and last name of a new user by passing in arguments or setting the attributes in the controller:

#UsersController
def new
   @user = User.new(first_name: 'John')
   @user.last_name = 'Smith'
end

In the view

#users/new.erb.html
<%= @user.first_name # will be John %> 
<%= @user.last_name # will be Smith %> 

But in your case, you're using update_attribute , which saves the record changes. Instead, you should be creating an instance variable, setting (but not saving) the values on that, and using that in the view/form

eg

@varibales = TemplateVariable.where(id: document_vars)
@variables.each do |variable|
  #change what you want here
  variable.foo = 'bar'
end

And then reference your @variables object in the view/form.

In saying all of that, you should strive to only use one instance variable in your controller, consider using form objects , if you need to pass multiple values from the controller to the view.

As for the flash notice, you can display whatever you like as a flash notice by setting that in the controller, assuming you've got your view setup to display flash notices as shown here

flash[:notice] = "The value of #{@variables.first.foo}"

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