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.