简体   繁体   中英

Rails - Hidden Model Attributes _Form

I recently finished the Rails Tutorial and I'm now working on my first app. Pushing through the fog of confusion

I want to create an "event" which is attached to a user.

def create
  @event = current_user.events.build(params[:event]) 
  if @event.save
      flash[:success] = "Event created!"
      redirect_to events_path
  else
    @feed_items = []
    render 'static_pages/home'
  end
end

With this, I can create an 'event' attached to a user, but when I build it will the wrong attributes (else) it sends me to 'static_pages/home'. I want it to tell the user what is wrong so they can correct

def create
  @event = Event.new(params[:event])

  respond_to do |format|
    if @event.save
      format.html { redirect_to @event, notice: 'Event was successfully created.' }
      format.json { render json: @event, status: :created, location: @event }
    else
      format.html { render action: "new" }
      format.json { render json: @event.errors, status: :unprocessable_entity }
    end
  end
end

With this setup, I must specify which user the event is attached to.

How do I find a median, where it will automatically attach an event to a specific user while sending the errors back to the form?

Thanks

Much of this code is modified from the Rails Tutorial.

It simple. Just like you scope the event to the current_user in your first example, do the same thing in the second example:

def create
  @event = current_user.events.build(params[:event])

  respond_to do |format|
    if @event.save
      format.html { redirect_to @event, notice: 'Event was successfully created.' }
      format.json { render json: @event, status: :created, location: @event }
    else
      format.html { render action: "new" }
      format.json { render json: @event.errors, status: :unprocessable_entity }
    end
  end
end

That said, something is weird about your setup. In general, the idiomatic way of writing create actions is to create the object, try and save it. If it successfully saves, you redirect to where you want your user to go. Otherwise you render the form again.

What does this mean for you? Well, using your first example:

def create
  @event = current_user.events.build(params[:event])
  if @event.save
      flash[:success] = "Event created!"
      redirect_to events_path
  else
    @feed_items = []

    # Change the following line to render the page that the event form is contained at
    # This way can render any errors and display the form again
    render 'static_pages/home'
  end
end

On another note, you can redirect and add flash in the same method:

flash[:success] = "Event created!"
redirect_to events_path

Becomes

redirect_to events_path, success: "Event created!"

Can't you just add the current_user into the code like this:

def create
  @event = current_user.new(params[:event])

  respond_to do |format|
    if @event.save
      format.html { redirect_to @event, notice: 'Event was successfully created.' }
      format.json { render json: @event, status: :created, location: @event }
    else
      format.html { render action: "new" }
      format.json { render json: @event.errors, status: :unprocessable_entity }
    end
  end
end

If you need to add your feed_items array, you can do it like this:

def create
  @event = current_user.new(params[:event])

  respond_to do |format|
    if @event.save
      format.html { redirect_to @event, notice: 'Event was successfully created.' }
      format.json { render json: @event, status: :created, location: @event }
    else
      format.html { 
        @feed_items = []
        render action: "new"
      }
      format.json { render json: @event.errors, status: :unprocessable_entity }
    end
  end
end

Note that redirect_to will redirect the browser and you will lose the scope of your form parameters. render will not redirect but instead will tell the controller to render the "new" view. The "new" view contains the form, so this keeps the form params in scope and the Rails form helpers will fill in the previously submitted details.

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