Ruby on Rails: using method name 'request' in controller fails - ruby-on-rails

I am at an absolute loss as to what I am doing wrong with the following code. I am trying to implement a messaging system within my application, but want it to be handle different types of messages. In this case, I want to create a "request" message of ':message_type => 1'.
Instead of using forms as I usually have, I want to make this instance the moment the link is clicked. Here is how I have it set up in the show erb file for "user":
<%=link_to "Send friend request", :action=>"request", :controller => "messages", :id => #user.id %>
and in the controller:
def request
#message = Message.new(:sender_id => current_user.id,:user_id => params[:id],:message_type => 1)
if #message.save
flash[:notice] = 'Message was successfully created.'
redirect_to message_path(#message)
else
redirect_to message_path(#message)
end
end
This results in the following error message: undefined method `rewrite' for nil:NilClass with the trace looking like
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.3.5/lib/active_support/whiny_nil.rb:52:in `method_missing'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.3.5/lib/action_controller/base.rb:634:in `url_for'
(eval):16:in `message_path'
app/controllers/messages_controller.rb:11:in `request'
I have used map.resources :messages in the routes.rb file, and done the appropriate :has_many and :belongs_to associations in the models of user and message.
EDIT: Something else to note is that the save IS succeeding, as once the root address is manually inputted into the address bar, the "flash" notice is shown saying that the save was made. Using the development console it is indeed there, so there's something messed up with the redirect.

You might want to rename the action, I am quite sure that request means something in the controller.
Why dont you rename the action from request to create, and see if it helps.
So the code will be:
In the view
<%=link_to "Send friend request", :action=>"create", :controller => "messages", :id => #user.id %>
In the controller
def create
#message = Message.new(:sender_id => current_user.id,:user_id => params[:id],:message_type => 1)
if #message.save
flash[:notice] = 'Message was successfully created.'
redirect_to message_path(#message)
else
redirect_to message_path(#message)
end
end

Check your logs more closely, and you'll probably find that your save is failing. Not sure which line is #11, but I would guess that it's in your else block, which tries to build a path for a #message object with a nil ID (it hasn't been saved).

Related

Unable to save merged articles

So I'm trying to create a feature for Typo (blogging app) that merges two articles in one. For some reason, I can't manage to save the merged article. I have followed several threads here, read over and over Rails and Ruby docs... And Can't figure out why it doesn't work
Besides finding what's wrong with my code, I'd like to know best solutions to see what's going on 'under the hood', to debug the code. Eg: See when methods are called, what parameters are passed...
Here is my code:
View:
<% if #article.id && #user_is_admin %>
<h4>Merge Articles</h4>
<%=form_tag :action => 'merge_with', :id => #article.id do %>
<%= label_tag 'merge_with', 'Article ID' %>
<%= text_field_tag 'merge_with' %>
<%= submit_tag 'Merge' %>
<% end %>
<% end %>
Controller
def merge_with
unless Profile.find(current_user.profile_id).label == "admin"
flash[:error] = _("You are not allowed to perform a merge action")
redirect_to :action => index
end
article = Article.find_by_id(params[:id])
debugger
if article.merge_with(params[:merge_with])
flash[:notice] = _("Articles successfully merged!")
redirect_to :action => :index
else
flash[:notice] = _("Articles couldn't be merged")
redirect_to :action => :edit, :id => params[:id]
end
end
Model:
def merge_with(other_article_id)
other_article = Article.find_by_id(other_article_id)
if not self.id or not other_article.id
return false
end
self.body = self.body + other_article.body
self.comments << other_article.comments
self.save!
other_article = Article.find_by_id(other_article_id)
other_article.destroy
end
Thanks in advance, and sorry if this is a rookie question :)
You did not mentioned what problem you are facing while saving, you just said you could not manage to save so I can't help you with that unless you provide some stack trace.
I will mention a few things though:
first is in your controller method you have multiple redirection code like redirect_to :action => index without any return from method so I think you will get multiple redirect or render error at some point like when unless executes and redirects but code continues the execution and throws error so try to reduce these redirects or mention it like redirect_to :action => index and return.
Then in model merge_with you are assigning other_article twice, you don't need the second one.
about debugging, you can create some puts line inside code and check it in rails server console to verify that the condition is executed like in controller method after if article.merge_with you can put:
puts "merge sucess"
and check console when merge action is called, if you see "merge sucess" then if block executed.
OR
use byebug like you used debugger. It will stop the execution where it will find the byebug word and will give access to a live session in rails console.
if you put it where you have debugger you can access the console and do the operations manually like run:
article.merge_with(params[:merge_with])
then see what happens. or put before self.save! in model and save it manually in console and check errors like self.errors.messages.
Stack trace is also helpful to see line by line code execution and identify the error.
I will update this if you post any info about what error you are facing

Implementing a specific action for a model that respond_with(#object)

I have a Subscription model that users can create. Users needs to validate a PIN sent to them to confirm subscription after is created. I'm having a bit of trouble trying to figure it out the best way to implement this.
I implemented a confirms controller with two new and create actions.
def new
#confirm = Subscription.new
end
def create
#keyword = Keyword.joins(:shortcode).where("shortcodes.shortcode = ? and shortcodes.country = ?",params[:subscription][:shortcode],params[:subscription] [:country]).find_or_create_by_keyword(params[:subscription][:keyword])
if #confirm = Subscription.where(:phone => params[:subscription][:phone], :country => params[:subscription][:country], :keyword_id => #keyword.id).last
#confirm.check_subscription_pin(params[:subscription][:pin])
respond_with(#confirm)
elsif #confirm && #confirm.errors.any?
flash[:notice] = #confirm.errors
render :action => :new
else
flash[:notice] = "Subscription not found."
render :action => :new
end
end
This solution doesn't look very convincing since I would like to always respond_with(#confirm) to allow REST POST done via JSON.
There's no params[:subscription] received when you make your curl call. Phone and Pin are nested within subscription, hence the error.
<pre>undefined method `[]' for nil:NilClass</pre>
I don't know how to make a curl call with nested params by the way.

Active Admin - flash messages not appearing on page

I am trying to display a notice after redirecting to a page but it doesnt appear.
Here is the redirect -
redirect_to :action => :index, :notice => "My redirect"
You can see the message in the url but there doesnt seem to be any code inside active admin to display it.
Any ideas how to render it inside active admin ?
There seems to be some issue that I haven't tracked down yet, but if you are looking for a work-around until then, this is what I did:
member_action :test do
flash[:notice] = "This is a test notice!"
redirect_to :action => :index
end
The problem that I am seeing is that when you put :notice in the redirect_to method, the notice message is url encoded and added to the URL
member_action :test do
redirect_to :action => :index, :notice => "This is a test notice!"
end
results in
/admin/model?notice=This+is+a+test+notice!
which is less than ideal. I noticed a change to the active_admin documentation that includes putting {} around the first parameter to redirect_to to fix this problem, however, for me, this results in an error.
member_action :test do
redirect_to {:action => :index}, :notice => "This is a test notice!"
end
which results in
syntax error, unexpected tASSOC, expecting '}'
redirect_to {:action => :index}, :notice => "This...
I posted a comment on that particular pull request # active_admin on github and hopefully someone might have another suggestion, since I am stumped.
In any event, maybe one of these solutions will work for you. Good luck.
Active Admin doesn't render flash messages, it believes they are rendered in t layout renders them.
When you run active_admin:install generator it mentions that:
$ rails g active_admin:install
...
Some setup you must do manually if you haven't yet:
...
3. Ensure you have flash messages in app/views/layouts/application.html.erb. For example:
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>

Conditional value for ActiveRecord create method only

I have a form where I have an administrator creating new users. The form uses the User model I created (login, password, first_name, etc...). For the last field on the form, I want to have a checkbox that doesn't need to be stored as part of the User record, but it is needed for the controller. This will control if the newly created user will receive a welcome email or not. This is in Rails 3.0.3.
def create
#user = User.new(params[:user])
if #user.save
if #user.send_welcome_email
UserMailer.welcome_email(#user).deliver
end
redirect_to(admin_users_url, :notice => "User #{#user.name} was successfully created.")
else
render :action => "new"
end
end
In my view (haml) I am trying to access it like this:
%p
Send Welcome Email?
= f.check_box :send_welcome_email
I tried to make this an attr_accessible: :send_welcome_email but the controller does not recognize it. I get an
undefined method 'send_welcome_email' for #<User:0x00000100d080a8>;
I would like it to look like this:
What is the best way to get this working?
What you want is not attr_accessible, but attr_accessor. That's it.
However, your code will look nicer if you move the email sending code to an observer.
Since you're not saving it on the user, you can use check_box_tag instead of f.check_box and access it with params[:send_welcome_email]. Although even the way you have it, I think you could access it as params[:user][:send_welcome_email].
As an alternative to attr_accessor, you can always remove it from the parameters first:
def create
send_welcome_email = params[:user].delete(:send_welcome_email)
#user = User.new(params[:user])
if #user.save
UserMailer.welcome_email(#user).deliver if send_welcome_email
redirect_to(admin_users_url, :notice => "User #{#user.name} was successfully created.")
else
render :action => "new"
end
end
You may have to make sure that the parameter is successfully transformed into a boolean; otherwise the condition will always be true (0 is true in Ruby).

Flash not surviving a redirect in Facebook on a Rails application

I have the following two action methods:
def index
puts "==index== flash: #{flash.inspect}"
end
def create
flash[:notice] = "Blah"
puts "==create== flash: #{flash.inspect}"
redirect_to(:action => :index)
end
index.fbml.erb contains this:
<%= button_to_with_facebooker "Blah!", :action => :create %>
The application is used through Facebook. I click the button and the flash contains the notice while create is being executed, but after that it's empty again. It doesn't survive a redirect. Any ideas what's going on here?
I've found one workaround. While using ActiveRecord to store the session, add
ActionController::Dispatcher.middleware.delete Rack::FacebookSession
ActionController::Dispatcher.middleware.insert_before(
ActionController::Base.session_store,
Rack::FacebookSession,
ActionController::Base.session_options[:key])
in an initialization file, like config/initializers/session_store_fix_facebooker_session_key.rb
This has been done on by someone else before and he explained it on a message on the Facebooker group on but it doesn't work with the cookie session storage, Rail's default.

Resources