Odd cancan issue... works on development machine, but not the server - ruby-on-rails-3

My ability model for cancan has been working well for 6+ months now. One of the controllers that has been around all that time is the QuestionsController. I recently added another controller, model and index page. The controller name is QuestionsBasicsController. In my ability model i have:
if user.permission >= 8 # admin
can :manage, [Question, QuestionsBasic]
end
At the top of QuestionsController and QuestionsBasicsController i have:
load_and_authorize_resource
I am able to access the index page for both QuestionsController and QuestionsBasicsController on my development machine. After I uploaded the ability model to my server i restarted the server. I can access the index page for Question but not for QuestionsBasic on my server. On my development machine i have ruby 1.9.2 while on my server i have 1.8.7. Could it be the Ruby version difference?
UPDATE: for what it is worth names of models that begin with the name of another model cause a problem,... at least with the way I have constructed my ability model. In addition, I recently found another model name that worked fine but for CanCan. I think it may have been a reserved word but am not positive on that. When I changed the name of the model, controller, route and code to a new name it passed CanCan. No reflection on CanCan though... I think it is AWESOME, AWESOME, AWESOME! Thanks, Ryan Bates!

agree with dleatham, try splitting your original statement into 2 lines:
if user.permission >= 8 # admin
can :manage, Question
can :manage, QuestionsBasic
end

Related

Rails 5 routing: why is "redirect_to #model" different than "redirect_to model_path(#model.id)"?

I am working on a Rails 5 app and have a model called #offer. In the Offers controller I have an action where I want to redirect to a specific offer I got from the database (Offer Id = 14 in the examples below.)
Working in the development environment, if I use redirect_to offer_path(#offer.id) in the controller, the browser correctly displays the offer in the https://dev.example.com/offers/14 URL. Notice the dev part in the URL. So far so good.
However, if I use redirect_to #offer in the controller, the browser tries to open the https://example.com/offers/14 URL (that's the production URL) and the page shows an error (We're sorry, but something went wrong.
If you are the application owner check the logs for more information.)
I would like to use redirect_to #offer, but first, I think I need to understand why one redirect method behaves differently than the other. Thanks for any insight.
This question is old but still I am answering as it might help other rails users in the future.
In Offers controller redirect_to #offer or redirect_to offers_path(#offer) would resolve to the same path /offers/:id be it production or development.
I think, in the production database offer with id 14 does not exist and also in the controller, if op is using find method without rescuing exception then, the show action might be erroring while trying to fetch the Offer with id 14 from the production database but the find method my have returned exception which if not rescued the rails might show a default error response.
We don't have controller code posted by the op but to me, this seems to be the most logical answer.

Rails 3 + Devise with different model name

I'm sharing one database for two web applications. The User model is already being used for one of these apps, so, in order to sign in to the other one, I had to create another model to avoid mixing users info.
I could make Devise work for this new model, called SystemUser. The problem is now I'll have to use every variable with another name. For example: current_system_user, system_user_signed_in?, etc. I'm using these variables, with their original name, across the whole application, and I would like to know if there's a way to avoid overwriting it. For example: by creating a method called current_user that returns current_system_user, and that way with the other variables mentioned before.
I think this should do the trick:
devise_for :users, class_name: 'SystemUser'
have you considered using CanCan for roles?
https://github.com/ryanb/cancan
I could finally solve the issue by generating the Devise views again. I don't know why, but the devise/sessions folder was missing, and it was doing it with another view, and when I started using it, it worked.
Thanks anyway.

disable caching for i18n phrases rails 3

I'm new to building a rails 3 app with multiple language support. The product requires that the translation team should be able to updated phrases from web interface and see its effects on refresh. They are not concerned about the performance hit this model carries.
So i'm using the gem i18n-active_record and its backend with i18n. The problem is, that translations stored in the db are not fetched on every request. I want the system to query the translations table for each key every time it gets the rendering request.
We're to disable this later when the site is mature enough, but this is an essential feature for now. Any ideas?
You could add in your ApplicationController:
before_filter { I18n.reload! }
I'm afraid I can't really comment on using i18n-active_record, but we run a staging server with the localeapp gem running in daemon mode. This means that translations can be editing via a GUI by a translator and they appear instantly on the staging server. Might be something worth looking into for you.
Disclosure: I'm a developer for Locale

How to create user specific content, that is invisible to others?

I am absolutely new to Ruby on Rails, even to programming at all. I got started with Michael Hartl's Rails Tutorial using Rails 3.0.10. Now I alter its aim towards creating an application that allows users to manage their own "projects". These projects are to be exclusively available to the logged-in user, thus, invisible to others.
My problem is: I am unable to create a page with an URL like "~/users/1/projects", I don't know about the routing. All i get done is "~/projects", which is fairly not what i want at all. So, how do I get this problem fixed? Or am I totally off track with that idea?
I generated a Projects model by scaffolding. So, how can I implement it for the signed-in users?
this would be done by creating a nested resource. when you are new to rails and programming you should work yourself a way through a lot of tutorials and guides.
a good place to get an overview are the official rails guides. in this specific case the chapter about routing: http://guides.rubyonrails.org/routing.html#nested-resources
# config/routes.rb
resources :users do
resources :projects
end

rails 3.1.1 engines - with mountable engines, is it possible to access parent app assets, default layout?

This is more for experimentation - I am aware that I can do this with --full but I wanted the functionality of namespacing in the app to avoid conflicts
The idea is to have a main app - which handles authentication, common items, admin screens etc
Then creating engines to add further functionality like
crm
cms
blog
wiki
forum
etc
These engines I can pick and choose as I need for whatever kind of app I am building.
Is this possible?
Is it just the case of applying both --mountable and --full options?
Experimenting - would there be any issue if I use the full option add rspec and then simple add
rails plugin new plugin_name --skip-test-unit --full --dummy-path=spec/dummy
and in lib\plugin_name\engine.rb
module PluginName
class Engine < Rails::Engine
# this is added by rails when an engine is mountable
# to isolate the plugin and prevent name clashes
isolate_namespace PluginName
# one of the additions to make rspec work from command line for the plugin
config.generators do |g|
g.test_framework :rspec, :view_specs => false
end
end
end
I have already created both --full and --mountable engines and have rspec finally working for anyone reading there are some great articles (see below), but wondered of the wider impact of doing this for the solution I am trying to create
I am still playing with this and will post my findings..
Any help/discussion will be massively appreciated.
Please Note
Why I want to do it - build once use many times...
I would never want a non-tech/client to add "plugins/engines" - this is purely to entertain point 1.
Issues I am Having...
Running the server on the top level app. Only when accessing content from the engine, (I can see by the error messages) I have a routing problem (root_path undefined or devise routes missing) - the parent application layout is being rendered, I can see it in the extracted source of the error. Progress but no cigar just yet!
Useful References
Engines vs Mountable Apps
3.1 engines with rspec
testing rails 3 engines
Listing Routes in a Mountable engine
I managed to get this working with the following steps:
In my parent app I was mounting the engine in routes.rb
mount PluginName::Engine => '/plugin_name'
I just removed it.
Created an application controller as Ryan Bigg below had stated.
class PluginName::ApplicationController < ApplicationController
...
end
As I wanted to have things name spaced when generating controllers, models, tests so you have to essentially comment out the isolate_namespace PluginName lib\plugin_name\engine.rb when I wanted the gem to be run in the parent app.
It is not yet an ideal solution. off the top off my head, I could use something like:
isolate_namespace PluginName if %w[development testing].include?(Rails.env)
but will have to test if this is practical.
Kudos to Ryan for helping me find my way many thanks
Furthermore, the same can be done with the --mountable switch version and all you need to do is one further step in your engines config/routes.rb replace
PluginName::Engine.routes.draw do
with
Rails.application.routes.draw do
Yes, you can reference the parent application assets just by referencing them in your application like normal:
<%= stylesheet_link_tag "application %>
Although, not sure why you would want to do that because...
I'm going to answer your first question with the answer to your second question.
To use the application's layout you will need to modify the ApplicationController in the engine (which is namespaced) and have it inherit from ApplicationController in the engine.
That will then have the controllers for the engine using the layout provided by the engine. I'm doing this in my engine, forem.
One day, this will be covered in the Engines Guide that, at this time of writing, is currently being written.