I am trying to override a model of forem gem so that I could use thumbs_up gem for voting purpose.
I did a rails g model Post and trying to inherit the post model of forem by this line of code
class Post < Forem::Post
acts_as_voteable
end
same for the controller
class PostsController < Forem::Postscontroller
def vote_up
begin
current_user.vote_for(#post = Post.find(params[:id]))
render :nothing => true, :status => 200
rescue ActiveRecord::RecordInvalid
render :nothing => true, :status => 404
end
end
end
I keep getting this error
undefined method `vote_up_post_path'
in my route.rb
mount Forem::Engine, :at => "/forums"
resources :posts do
member do
post :vote_up
end
end
I guess I am doing something really stupid out here and I am not overriding the model correctly. I was using this Clarification on how to use "thumbs_up" voting gem with Rails 3 post to set up thumbs_up
Can someone help??
If I'm getting your question correctly, you wanna change the behavior of forem Post in order to support voting using acts_as_votable.
For that to work you need to re-open Forem::Post class in an initializer (e.g. config/initializers/forem.rb) and add to it acts_as_votable line like this:
module Forem
class Post
acts_as_votable
end
end
And the same for Forem::PostsController:
module Forem
class PostsController
def vote_up
begin
current_user.vote_for(#post = Post.find(params[:id]))
render :nothing => true, :status => 200
rescue ActiveRecord::RecordInvalid
render :nothing => true, :status => 404
end
end
end
end
It seems it was a stupid mistake, realized it while having discussion with patrickmcgraw.
forem hides your routes and and you have to mention main_app before the routes, so after writing
main_app.vote_up_post_path instead of vote_up_post_path the page was up again.
Hope it helps someone trying to use forem.
Related
Having a controller handling rendering of large XML feeds
module Spree
class FeedsController < Spree::StoreController
...
caches_action :products_out
cache_sweeper FeedSweeper
# XML feed in format of `xxxxxxx.com'
def products_out
#products = Product.all
respond_to do |format|
format.xml
end
end
end
Bellow is the corresponding sweeper's sublass:
module Spree
class FeedSweeper< ActionController::Caching::Sweeper
observe Product
def after_update(product)
# cache_configured? is nil, #controller is nil here, why ?
expire_action(:controller => :feeds,
:action => :products_out,
:format => :xml)
end
end
Above Spree::FeedSweeper is called when Spree::Product gets updated, however it seems expire_action silently dies and cache won't get invalidated.
Can somebody explain the issue ? Even better suggest some solution ?
Thanks.
Which Rails version are you using? expire_action seems to be deprecated after Rails 3.2.14.
Maybe you can try to find out the key then directly clear it with Rails.cache.delete(key).
I am using Clearance 1.1.0 gem with Ruby on Rails 4.0.1. I am trying to override the sessions controller to provide my own custom method. I have not been able to successfully get rails to use my controller.
/app/controllers/sessions_controller.rb
class SessionsController < Clearance::SessionsController
private
def flash_failure_after_create
flash.now[:notice] = translate(:bad_email_or_password,
:scope => [:clearance, :controllers, :sessions],
:default => t('flashes.failure_after_create', :new_password_path => new_password_path).html_safe)
end
end
I have tried a few different things inside my routes.rb file, and have been unsuccessful. I want to change the route sign_in.
get '/sign_in' => 'sessions#new', :as => 'sign_in'
Yields the following error.
You may have defined two routes with the same name using the :as
option, or you may be overriding a route already defined by a resource
with the same naming.
Any ideas? Thank you!
Edit: I made a mistake. I actually need sessions#create to use my controller. I'm trying to pass a different variable to the yaml file for the flash when the session login fails.
Edit 2: I the appropriate session#create line to to my routes. In my session controller, I copied and edited for testing the flash_failure_after_create method. It is not being called. So I then copy the create method over. Now, my create method is being called, but not my flash_failure_after_create method. To get it to be called, I had to have the create method copied from gem, and changed status.failure_message to directly call the flash_failure_after_create method. Is this some sort of bug with clearance?
routes.rb
post 'session' => 'sessions#create', :as => nil
sessions_controller.rb
class SessionsController < Clearance::SessionsController
def create
#user = authenticate(params)
sign_in(#user) do |status|
if status.success?
redirect_back_or url_after_create
else
#flash.now.notice = status.failure_message
flash.now.notice = flash_failure_after_create
render :template => 'sessions/new', :status => :unauthorized
end
end
end
private
def flash_failure_after_create
# Changed flash for easy testing
flash.now[:notice] = 'Ballz.'
#flash.now[:notice] = translate(:bad_email_or_password,
# :scope => [:clearance, :controllers, :sessions],
# :default => t('flashes.failure_after_create', :sign_up_path => sign_up_path).html_safe)
end
end
I believe this will work:
get '/sign_in' => 'sessions#new', :as => nil
Rails 4 no longer supports overriding route names, so don't name your override. The mapping is still the same so sign_in_path should still work.
I am trying to integrate forem with thumbs_up. I have inherited the forem Post model and controller.
Here is my controller :-
class PostsController < Forem::PostsController
def vote_up
begin
current_user.vote_for(#post = Post.find(params[:id]))
render :nothing => true, :status => 200
rescue ActiveRecord::RecordInvalid
render :nothing => true, :status => 404
end
end
end
Here is how the Post Controller of Forem looks like :-
module Forem
class PostsController < Forem::ApplicationController
before_filter :authenticate_forem_user
before_filter :find_topic
.
.
.
.
private
def find_topic
#topic = Forem::Topic.find(params[:topic_id])
end
end
end
Here is my routes:-
mount Forem::Engine, :at => "/forums"
resources :posts do
member do
post :vote_up
end
end
Here is my view :-
<%= link_to t('vote for this post!', :scope =>"forem.post"), main_app.vote_up_post_path(#post), :method => :post %>
This is the error which I am getting :-
ActiveRecord::RecordNotFound in PostsController#vote_up
Couldn't find Forem::Topic without an ID
What could be the issue?
Your problem is the before filter:
module Forem
class PostsController < Forem::ApplicationController
#...
before_filter :find_topic
#...
def find_topic
#topic = Forem::Topic.find(params[:topic_id])
end
and then:
class PostsController < Forem::PostsController
def vote_up
#...
So find_topic will be called before vote_up but the route for vote_up won't have a :topic_id; no :topic_id means that find_topic will be doing this:
#topic = Forem::Topic.find(nil)
and that's where your error comes from.
Three options come to mind:
Move vote_up to a separate controller class that doesn't inherit from Forem::ApplicationController.
Add a skip_filter :find_topic, :only => :vote_up to PostsController.
Adjust the route and link to get a :topic_id in the route.
If upvoting doesn't need the #topic then (1) or (2) would work, otherwise you'll have to go with (3).
check rake routesin command prompt,
and check id should be post :vote_up OR get:vote_up – ror_master
and use debugger in controller!
and write params there perhaps you will get solution.
There are conflict with inherited_resources and Ryan Bates's cancan gem.
I have some simple controller
class IssuesController < InheritedResources::Base
respond_to :html
load_and_authorize_resource
def tag
#issues = Issue.tagged_with(params[:tag]).recent.paginate(:page => params[:page])
end
protected
def collection
#issues = end_of_association_chain.recent.paginate(:page => params[:page], :per_page => Settings.per_page_defaults.issues)
end
end
and route
resources :issues do
collection do
get "tag/:tag" => "issues#tag", :as => "tags"
end
end
Everything looks correct, but on attempt to request http://localhost:8080/issues/tag/tag1
i see
ActiveRecord::RecordNotFound in IssuesController#tag
Couldn't find Issue without an ID
After removing load_and_authorize_resource from controller - everything works fine, but i need access control.
Any idea how to solve this issue?
use load_and_authorize_resource :except => :tag. Note that this wont apply rules. If you need to apply some use authorize! instead.
I need to implement a custom error page in my rails application that allows me to use erb.
I've been following this tutorial (http://blog.tommilewski.net/2009/05/custom-error-pages-in-rails/) and I cannot get it to work locally (or remotely). I am running Rails 2.3.5
Here's the gist of the approach.
1) in the 'application_controller', I over ride the "render_optional_error_file(status_code)" method, and set the visibility to "protected", like this.
protected
def render_optional_error_file(status_code)
known_codes = ["404", "422", "500"]
status = interpret_status(status_code)
if known_codes.include?(status_code)
render :template => "/errors/#{status[0,3]}.html.erb", :status => status, :layout => 'errors.html.erb'
else
render :template => "/errors/unknown.html.erb", :status => status, :layout => 'errors.html.erb'
end
end
def local_request?
true
end
I also created a folder within views called errors and created the following views: 404.html.erb, 422.html.erb, 500.html.erb,unknown.html.erb and I created a new layout "errors.html.erb"
I can't seem to get it to work. I've been trying to trigger the 404 page by navigating to http://localhost:3000/foobar -- but, instead of getting the new 404.html.erb, I seem to be getting the standard apache 500 error. This happens when I try both mongrel_rails start and mongrel_rails start -e production.
I would suggest using exceptions to render such error pages, so you can use inheritance to group your error messages...
First, declare some (I usually do it in application_controller.rb)
class Error404 < StandardError; end
class PostNotFound < Error404; end
Then add code to ApplicationController to handle them
class ApplicationController < ActionController::Base
# ActionController::RoutingError works in Rails 2.x only.
# rescue_from ActionController::RoutingError, :with => :render_404
rescue_from Error404, :with => :render_404
rescue_from PostNotFound, :with => :render_post_not_found
def render_404
respond_to do |type|
type.html { render :template => "errors/error_404", :status => 404, :layout => 'error' }
type.all { render :nothing => true, :status => 404 }
end
true
end
def render_post_not_found
respond_to do |type|
type.html { render :template => "errors/shop_not_found", :status => 404, :layout => 'error' }
type.all { render :nothing => true, :status => 404 }
end
true
end
end
This renders errors/error_404 with the errors layout. Should get you started :)
And in your target_controller:
raise PostNotFound unless #post
Edit
Note for Rails 3
for a longer explanation on why ActionController::RoutingError doesn't work for rails 3:
Rails 3.0 Exception Handling.
Rails ticket 4444
"If your application relies on engines that extend your app with their
own routes, things will break because those routes will never get
fired!"
Firstly - have you deleted the file: 'public/500.html' If that file exists, it will override anything else that you try to do.
Secondly, using an explicit "rescue_from" in the controller (as explained in the other comment) - is a good option if you need to fine-tune the response to different kinds of errors.
You most likely get the 500 error because of an application error.
Have you checked the log files?
Update:
Are you certain that you are running 2.3.5 and not an older version that happens to be installed?
Mongrel should say which version you are running when it starts, otherwise it should say in the config/environment.rb file.
There are some errors in the code that might create the 500 error. I've changed that and also corrected a few other things I think you meant :)
def render_optional_error_file(status_code)
known_codes = ["404", "422", "500"]
status = interpret_status(status_code)
if known_codes.include?(status) # Here it should be status, not status_code (which is a symbol)
render :template => "errors/#{status[0,3]}", :status => status, :layout => 'errors' # No need to mention ".html.erb", you can do it, but it is not necessary since rails will guess the correct format.
else
render :template => "errors/unknown", :status => status, :layout => 'errors'
end
end
def local_request?
# This must return false instead of true so that the public viewer is called
# instead of the developer version.
false
end
Purpose of completeness for newer rails versions:
http://www.frick-web.com/en/blog/nifty_errorpages-gem
that is a little rails engine for handling your error pages. Maybe you will need it for newer projects. it is a good option to handle errors in my opinion.