I'm developing an application with optional sign up. I want to allow users, with and without accounts, to be able to add links. How could I assign a user's session[user_id] to the user_id column of Link if they're signed in when creating a link?
Current code: user_id remains nil in either case
def create
#link = Link.new(params[:link])
if #link.save
flash[:notice] = "The link was successfully added"
redirect_to :action => :hot
else
redirect_to :action => :new
end
end
I'm imagining something like this..
def create
if session[:user_id]
##link equals new link params with user_id = session[:user_id]
else
#link = Link.new(params[:link])
end
if #link.save
flash[:notice] = "The link was successfully added"
redirect_to :action => :hot
else
redirect_to :action => :new
end
end
def create
#link = Link.new params[:link]
#link.user_id = session[:user_id] if session[:user_id]
if #link.save
redirect_to { action: 'hot' }, notice: 'The link was successfully added'
else
render :new
end
end
The link will be saved with params[:link] even if the user isn't logged-in.
Be cautious to use render, not redirect_to, when a validation fails (see if you want http://guides.rubyonrails.org/action_controller_overview.html)
Related
I have a form that's working perfectly:
def update
#post = Post.find(params[:id])
if #post.update_attributes(post_params)
flash[:notice] = 'Blog post updated.'
redirect_to(:action => 'index')
else
render("edit")
end
end
But if the user leaves a form blank before submit, I then want to pass in a variable. Otherwise the user submitted value is stored. I can't quite get the syntax right, I need something like this:
def update
if params[:permalink] == nil
params[:permalink] = "#{defaultValue}"
end
#post = Post.find(params[:id])
if #post.update_attributes(post_params)
flash[:notice] = 'Blog post updated.'
redirect_to(:action => 'index')
else
render("edit")
end
end
The code doesn't seem to grab onto the params[:permalink] before save when there is in fact a :permalink field in the form. Any suggestions?
Solution:
def update
if !params[:post][:permalink].presence
params[:post][:permalink] = "#{defaultValue}"
end
#post = Post.find(params[:id])
if #post.update_attributes(post_params)
flash[:notice] = 'Blog post updated.'
redirect_to(:action => 'index')
else
render("edit")
end
end
I would like to render on the same page if email is blank. However, when I leave in blank instead of staying on users/new. It goes to /users. It is still render to _from for the URL is different.
def new
respond_with(user)
end
def create
if user.save
user.send_invitation
redirect_to root_url, notice: "Signed up!"
else
render "/users/new"
end
end
def destroy
#user = User.find(params[:id])
if #user.destroy
redirect_to root_url, notice: "User was deleted successfully!"
end
end
def edit
respond_with(user)
end
def update
params[:user].delete(:password) if params[:user][:password].blank?
params[:user].delete(:password_confirmation) if params[:user][:password_confirmation].blank?
if user.save
redirect_to users_path, :notice => "Saved your updates!"
else
render :edit
end
end
render "/users/new"
Just renders template users/new, at create action. So the URL stays /users.
You can try to
def create
if user.save
user.send_invitation
redirect_to root_url, notice: "Signed up!"
else
redirect_to new_user_path
end
end
But then you will have no access to submitted params, so the form will be clear.
The thing in here I think it's a routes problem, as you want to persist the URL.
What Rails does in this cases is it goes to the create action once the form was submitted and if for some reason the record is not being save(in this case) you are rendering the new action but with the object which has errors and data.
To clean up a little bit you could do something like:
def create
if user.save
user.send_invitation
redirect_to root_url, notice: "Signed up!"
else
render :new
end
end
In my opinion, don't try to bend Rails this way, you'll get a lot of problems with it and also, does it really matters to persist the URL?
Redirection is not an option, because you'll loose all the data from the request, as it would become a new request due to the redirect.
Hope this helped!
Im doing some testing on my app.
I have a form that accepts a city(autocompleted by city name), and some dates.
Because I have a autocomplete feature, I have to get the city_id by looking up the city by its display name.
def trip_params
params.require(:trip).permit(:start_date, :end_date).merge(:city_id => City.find_by_display(params[:trip][:city_id]).id)
end
The problem is if the user sumbits the form without a city. I get an error:
undefined method `id' for nil:NilClass
Because there was no record found. Whats a better way to structure this so that I can redirect back to 'new' if no city is entered?
create method just in case its helpful.
def create
#trip = current_user.trips.build(trip_params)
if #trip.save
flash[:success] = "Trip to #{#trip.city.name} added."
redirect_to root_path
else
flash.now[:error] = #trip.errors.full_messages
render 'new'
end
end
def create
if params[:trip][:city_id].blank?
flash[:error] = "some warning about the city"
render new
else
#trip = current_user.trips.build(trip_params)
if #trip.save
flash[:success] = "Trip to #{#trip.city.name} added."
redirect_to root_path
else
flash.now[:error] = #trip.errors.full_messages
render 'new'
end
end
end
or
def trip_params
if !params[:trip][:city_id].blank?
params.require(:trip).permit(:start_date, :end_date).merge(:city_id => City.find_by_display(params[:trip][:city_id]).id)
end
end
I have a rails app with a page for a user to edit their own profile
app/views/manage_users/edit.html.erb and app/views/manage_users/new.html.erb contain:
<%= render 'form' %>
app/views/manage_users/_formt.html.erb contains:
<%= form_for(#user, :as => :user, :url => {:action => #form_action, :id => #user.id}) do |f| %>
When I fire up the page http://localhost:3000/manage_users/2/edit it shows me a typical form to edit a user object's data. If i blank out the email address http://snag.gy/atnmV.jpg and submit the form, I get an error that I would expect http://snag.gy/NRfwn.jpg and the url is now http://localhost:3000/manage_users/2:
Started PUT "/manage_users/2" for 127.0.0.1 at 2014-01-25 21:01:45 -0600
Processing by ManageUsersController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"B44/1b5m8usyAfe0hzLHNyjk/7Fpn5iEu3u6wGJMGL0=", "user"=>{"user_details_attributes"=>{"first_name"=>"Jeff", "last_name"=>"Smith", "id"=>"2"}, "email"=>"", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "button"=>"", "id"=>"2"}
If i put the email address back in and submit the form, the url now points to http://localhost:3000/manage_users?id=2 and I get the error No route matches [PUT] "/manage_users"
Why is it doing this and how can I fix it. If i just go to the initial page to edit a user and save it right away (instead of blanking out the email), everything works just fine.
app/controllers/manage_users_controller.rb
class ManageUsersController < ApplicationController
before_filter :admin_only, :except => [:edit, :update]
# GET /manage_users
# GET /manage_users.json
def index
#users = User.active
respond_to do |format|
format.html # index.html.erb
format.json { render json: #users }
end
end
# GET /manage_users/new
# GET /manage_users/new.json
def new
#user = User.new
#user.build_user_details
#form_action = 'create'
respond_to do |format|
format.html # new.html.erb
format.json { render json: #user }
end
end
# GET /manage_users/1/edit
def edit
#user = User.find(params[:id])
#permissions_disabled = params[:id].to_i == current_user.id.to_i
#p #permissions_disabled
able_to_edit_profile?
session[:return_to] ||= request.referer
#form_action = 'update'
end
# POST /manage_users
# POST /manage_users.json
def create
#user = User.new(params[:user])
#p "in create"
respond_to do |format|
if #user.save
format.html {
flash[:notice] = 'User was successfully created.'
redirect_to(:action => :index)
}
format.json { render json: #user, status: :created, location: #user }
else
format.html { render action: "new", notice: 'Error creating user.' }
format.json { render json: #user, status: :unprocessable_entity }
end
end
end
# PUT /manage_users/1
def update
#user = User.find(params[:id])
able_to_edit_profile?
# required for settings form to submit when password is left blank
if params[:user][:password].blank?
params[:user].delete("password")
params[:user].delete("password_confirmation")
end
respond_to do |format|
if #user.update_attributes(params[:user])
#user.save
# sign the user in with their new password so it doesn't redirect to the login screen
if current_user == #user
sign_in #user, :bypass => true
end
format.html {
p "in success format.html"
flash[:notice] = 'User was successfully updated.'
redirect_to session.delete(:return_to)
}
else
p "in else"
format.html { render action: "edit", notice: 'Error updating user.' }
#format.html {
#flash[:notice] = #user.errors
# redirect_to edit_manage_user_path(#user)
#}
end
end
end
private
# If the user is not an admin and trying to edit someone else's profile, redirect them
def able_to_edit_profile?
if !current_user.try(:admin?) && current_user.id != #user.id
flash[:alert] = "That area is for administrators only."
redirect_to :root
end
end
end
EDIT
So by changing this:
format.html { render action: "edit", notice: 'Error updating user.' }
to:
format.html {
flash[:notice] = #user.errors.full_messages.to_sentence
redirect_to edit_manage_user_path(#user)
}
I'm able to circumvent the issue. I'm still curious as to why rendering 'edit' doesn't work after a failed update.
When you render the edit action from the update method (in the failure path), it doesn't run the edit method, so #form_action is nil when you render the form. You'll need to address that.
I usually don't need to set the url, only in rare cases do I. You may be able to leave that out and let rails take care of the url and HTTP method.
def create
#purchase = Purchase.new(params[:purchase])
if session[:purchase_id] != #purchase.save
redirect_to(#purchase, :notice => "Thank you. You good lookin person you.")
end
end
I'm trying to either
A - Redirect to a URL, or other controllers path, or
B - refresh the form they ordered from (the new_purchases_path) and flash :notice the user that their purchase was successful. When I try to add a Url (that would be a thank you message page) i get syntax errors. This code redirects the user to the index list (which is inaccesible to them)
If I take out the def create, it by default flashes a notice and shows them their completed form. I'm using simple_form and I'm not sure how to override those defaults. Any suggestions on at least redirecting to a url?
Examples:
A - Redirect to a URL, or other controllers path
redirect_to :action => "show", :id => 5
redirect_to "http://www.rubyonrails.org"
redirect_to new_purchases_path
redirect_to purchases_url
redirect_to :back
B - refresh the form they ordered from (the new_purchases_path)
render :action => "new"
Edit:
Here a general example with flash messages:
if #foo.save
redirect_to foos_path, :notice => "Foo saved"
else
flash[:notice] = "Some errors occured"
render :action => "new"
end
here is an example of a create method i made today
def create
#book = Book.new(params[:book])
if #book.save
redirect_to searchbook_path, notice: 'Book was successfully saved'
else
render :action => 'results'
end
end
So in your case you could maybe try this
def create
#purchase = Purchase.new(params[:purchase])
if #purchase.save
redirect_to purchase_path, :notice 'Thanks for your purchase'
else
render :action => 'new'
end
end
This is assuming that you have a purchase and new path... Though it would help if you could let us know what errors you are getting