Rails - attribute is not saved - ruby-on-rails

I have this code:
if request.post? and #user.save
#contact.user_id = #user.id
#contact.save
flash[:notice] = l(:e_user_saved)
redirect_to :action => 'list'
end
But when rails saves the contact, the user_id remains null.
When I debug I see that it assigns the value, but when it saves it saves null. Why???

contact.save probably failed. You're not checking the return value, so you don't know.
Check the contact.errors hash to see what went wrong.
You should probably have contact.save in an if block:
if #contact.save
flash[:notice] = l(:e_user_saved)
redirect_to :action => 'list'
else
# some error handling
# and redirect somewhere else
end

Related

Rails controller method executes code in both the "if" and "else" statement

I have a friendship model that allows users to become friends in my Rails app. It stores the following data:
friendship_id (int), sender_id (int), receiver_id (int), sent_at (datetime), accepted (boolean), accepted_at (datetime)
The following controller method is for adding friends
def addfriend
if user_signed_in?
#sender = params[:sender]
#receiver = params[:receiver]
if Friendship.find_by(sender_id: #sender, receiver_id: #receiver).nil? &&
Friendship.find_by(sender_id: #receiver, receiver_id: #sender).nil?
#friend = Friendship.create(friendship_id: 0, sender_id: #sender, receiver_id: #receiver, sent_at: DateTime.now, accepted: false)
if #friend.save
flash[:success] = "Friend request sent"
redirect_to root_path
else
flash[:error] = "Oops, something went wrong."
redirect_to root_path
end
else
flash[:notice] = "Already friends with this person or friendship pending acceptance."
redirect_to root_path
end
end
end
What happens is the friend request gets sent, it will be there in the database and when I switch to the other user the request will be there, but the notification that pops up after the request was sent and the page reloads says "Already friends with this person or friendship pending acceptance." As if the request wasn't actually sent, even though it was. This even happens when all Friendships have been deleted in the database.
Any thoughts as to why this is happening? I want it to say "Friend request sent" when it does get sent, rather than what it is saying now.
redirect_to doesn't return from the method and continues the execution.
You need to do:
redirect_to root_path and return
or:
return redirect_to root_path
Try this
redirect_to :controller =>… , :action=>….
for example
def update
#tip = current_user.tips.find(params[:id])
#tip.attributes = params[:tip]
#tip.category_ids = params[:categories]
#tip.tag_with(params[:tags]) if params[:tags]
if #tip.save
flash[:notice] = 'Tip was successfully updated.'
redirect_to :controller=>'tips', :action => 'show', :id => #tip.permalink
else
render :action => 'edit'
end
end

Rails Controller Def Create Redirect to URL upon Save

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

How to avoid the error on nil object

Record id 116 doesn't exist so it should return nil to #conversation.
I tried to make it redirect when it gets nil, but it still shows the error when I access example.com/messages/show?id=116 .
The error is
undefined method `is_participant?' for nil:NilClass
I definitely see 'is_participant' method existing in
/usr/local/lib/ruby/gems/1.9.1/gems/mailboxer-0.7.0/app/models/conversation.rb
messages_controller.rb
def show
#conversation = Conversation.find_by_id(params[:id])
unless #conversation.is_participant?(current_user)
flash[:alert] = "You do not have permission to view that conversation."
redirect_to :controller => 'messages', :action => 'received'
end
#messages = Message.find_by_id(params[:id])
current_user.read(#conversation)
end
You need to check that #conversation is not nil before you call a method on it. Try
unless #conversation.present? && #conversation.is_participant?(current_user)
You can check for presence of a value or rescue for that error.
def show
#conversation = Conversation.find_by_id(params[:id])
redirect_to somewhere_path if #conversation.nil?
unless #conversation.is_participant?(current_user)
flash[:alert] = "You do not have permission to view that conversation."
redirect_to :controller => 'messages', :action => 'received'
end
#messages = Message.find_by_id(params[:id])
current_user.read(#conversation)
end
or the Rescue!
def show
#conversation = Conversation.find_by_id(params[:id])
unless #conversation.is_participant?(current_user)
flash[:alert] = "You do not have permission to view that conversation."
redirect_to :controller => 'messages', :action => 'received'
end
#messages = Message.find_by_id(params[:id])
current_user.read(#conversation)
rescue NoMethodError
redirect_to somewhere_path
end
Notice that the rescue way is not very friendly, since it can rescue other error and making you have a pain to debug some errors. For example if current_user has no method named read, it would throw and error that would be catch there and you wouldn't notice it came from there.
Christoph Petschnig answer is right, just wanted to mention there is a nice shorthand for
unless #conversation.present? && #conversation.is_participant?(current_user)
which is
unless #conversation.try(:is_participant? , current_user)
try will return nil is #conversation is nil which eventually evaluates to false in the if statement.

Rails Optional Sign Up - Changing Params Before Saving

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)

ruby on rails session information grab

When i run in my page this code :
<% user = User.find(session[:userid]) %>
i get the error :
line #1 raised:
Couldn't find User without an ID
although i have in my authentification in my sessions_controller this :
def create
if user = User.authenticate(params[:username],params[:password])
session[:user_id]= user.id
session[:language_id]= user.language_id
User.find(user.id).update_attributes(:last_login => Time.now)
redirect_to root_path , :notice => (I18n.t :"session.login_success")
else
flash.now[:alert] = (I18n.t :"session.error")
render :action => 'new'
end
end
and the session should contain the userid
In your log-in you set session[:user_id], and you try to find session[:userid] (note the spurious underscore). That's why.
Your controller is looking for params session[:user_id], but in your views it is session[:userid] so it will complain that session[:user_id] is nil.

Resources