Rails 3 Devise customization - ruby-on-rails-3

I have an app that uses 2 type of roles: users and admins. For the users I have overwritten both the RegistrationController and PasswordsController but after adding the PasswordsController the login page for the admin(different from the user, which is custom) gives the following routing error:
Routing Error
No route matches {:action=>"create", :controller=>"password_resets", :locale=>:admin}
this is my routes.rb file:
AppName::Application.routes.draw do
devise_for :admin
namespace :backend do
root :to => "home#index"
resources :exchanges, :except => :show
resources :prices, :except => :show
resources :offers
resources :newss
resources :users, :except => :show
scope ':locale', :locale => /en|ro/ do
namespace :profile do
root :to => 'home#index'
resources :orders do
resources :items
end
end
devise_for :users, :skip => [:sessions, :registrations, :passwords]
devise_scope :user do
get 'logare' => 'registrations#logare', :as => :new_user_session
post 'logare' => 'devise/sessions#create', :as => :user_session
delete 'index' => 'devise/sessions#destroy', :as => :destroy_user_session
get 'inregistrare' => 'registrations#new', :as => :new_user_registration
post 'inregistrare' => 'registrations#create', :as => :user_registration
get 'get_city_list' => 'registrations#get_city_list', :as => :get_city_list
get 'edit' => 'registrations#edit', :as => :user_edit
post 'edit' => 'registrations#update', :as => :user_update
get 'new_password' => 'password_resets#new', :as => :password_reset
post 'new_password' => 'password_resets#create', :as => :new_password
get 'edit_password' => 'password_resets#edit', :as => :edit_password_reset
post 'edit_password' => 'password_resets#update', :as => :update_password
end
end
match '/:locale' => 'home#index'
root :to => 'Home#index'
match '*a', :to => 'errors#routing'
end
but as I was saying, this url /admin/sign_in gives the routing error mentioned.
Dunno what I'm missing. If I remove the PasswordsController, it all works again.
PS: here is the PasswordResetsController:
class PasswordResetsController < ApplicationController
def new
end
def create
user = User.find_by_email(params[:email])
user.send_password_reset if user
redirect_to new_user_session_path, :notice => t('password_reset_notice')
end
def edit
#user = User.find_by_reset_password_token!(params[:reset_token])
end
def update
#errors_user = nil
#user = User.find_by_reset_password_token!(params[:token])
if #user
if #user.reset_password_sent_at < 2.hours.ago
redirect_to password_reset_path, :alert => t('password_expired')
else
#user.password = params[:user][:password]
#user.password_confirmation = params[:user][:password_confirmation]
unless #user.save
#errors_user = #user.errors.full_messages.join(';<br/>') + '.'
end
unless #errors_user.nil?
#reset_token = params[:token]
render :edit
else
redirect_to new_user_session_path, :notice => t('password_change_success')
end
end
end
end
end
my login form (for users, for admin I use the standard devise one):
<div class='signin-container'>
<%= form_for(:user, :url => user_session_path(#user)) do |f| %>
<%= f.label :email, 'Email:', :id => 'username_label', :class => 'general-signin' %>
<%= f.text_field :email, :id => 'username-field', :class => 'general-signin' %>
<%= f.label :password, t('inregistrare.parola'), :id => 'pass_label', :class => 'general-signin' %>
<%= f.password_field :password, :size => 23, :id => 'pass-field', :class => 'general-signin' %>
<%= f.check_box :remember_me, :id => 'remember' %>
<%= f.label :remember_me, :id => 'remember-label' %>
<%= f.submit "", :class => 'general-signin', :id => 'buton-signin' %>
<% end %>
<a href=<%= new_user_registration_path %>><span class='creeaza'><%= t('logare.creeaza') %></span></a>
<a href=<%= password_reset_path %>><span class='forgot-pass'><%= t('forgot_password') %></span></a>
</div>

figured it out ... had to generate the devise views and edit shared/_links.erb
<%= link_to "Forgot your password?", new_password_path(resource_name) %><br />
became
<%= link_to "Forgot your password?", new_password_path(:locale => I18n.locale) %><br />

Related

Routes error on nested controller when submitting form, databasedotcom-gem

I am using the databasedotcom & databasedotcom-rails gem so that I get generate leads into Salesforce from form submissions. It was working standalone until I nested the controller under a parent, and now when I press submit I get this routes error:
No route matches [POST] "/events/516ee9a0421aa9c44e000001/leads/new"
Here is all my code:
resources :events do
resources :leads
end
class LeadsController < ApplicationController
include Databasedotcom::Rails::Controller
def new
#lead = Lead.new
respond_to do |format|
format.html # new.html.erb
format.json { render :json => #lead }
end
end
def create
#lead = Lead.new(params[:lead])
#lead.event_id = params[:event_id]
#lead['OwnerId'] = '005b0000000WxqE'
#lead['IsConverted'] = false
#lead['IsUnreadByOwner'] = false
respond_to do |format|
if #event_lead.save
format.html { redirect_to #lead, :notice => 'Lead was successfully created.' }
format.json { render :json => #lead, :status => :created, :location => #lead }
else
format.html { render :action => "new" }
format.json { render :json => #lead.errors, :status => :unprocessable_entity }
end
end
end
end
<%= simple_form_for [#event, #lead], url: new_event_lead_path do |f| %>
<%= f.input :Download_Brochure__c, :check => "true", :as => :boolean, :as => :hidden %>
<%= f.input :FirstName %>
<%= f.input :LastName %>
<%= f.input :Company %>
<p>Also interested in:</p>
<%= f.input :Sponsor_Request__c, :as => :boolean, :label => "Sponsoring" %>
<%= f.input :Presenting__c, :as => :boolean, :label => "Presenting" %>
<%= f.input :Newsletter_Signup__c, :as => :boolean, :label => "Newletter" %>
<%= f.input :Privacy_Policy__c, :as => :boolean, :checked => true, :label => "Would you like to stay updated" %>
<%= f.button :submit, :label => "Submit" %>
<% end %>
The problem is in your form. With the routes as you have written them, the new_event_lead_path maps to a GET request to your LeadsController#new action. Run rake routes on the command line to confirm this.
You want to submit the form to LeadsController#create. Rails will set this up for you when you use a new instance of Lead in the expression simple_form_for [#event, #lead] provided you don't override the url. Therefore, update your form:
<%= simple_form_for [#event, #lead] do |f| %>

ruby on rails app tutorial can't display micropost page

Hi I'm following a rails tutorial and i've kind of veered off the tutorial to do some different things...& i hit a snag. So the tutorial (michael hartl's) creates a feed of microposts, but it doesn't give each micropost its own page. This is what i'm trying to do and can't seem to get it working.
So in the feed view which i'm calling "activity" i've got:
<li id="<%= activity_item.id %>">
<%= link_to gravatar_for(activity_item.user, :size => 200), activity_item.user %><br clear="all">
<span class="title"><%= link_to activity_item.title, #micropost %></span><br clear="all">
<span class="user">
Joined by <%= link_to activity_item.user.name, activity_item.user %>
</span><br clear="all">
<span class="timestamp">
<%= time_ago_in_words(activity_item.created_at) %> ago.
</span>
<% if current_user?(activity_item.user) %>
<%= link_to "delete", activity_item, :method => :delete,
:confirm => "Are you sure?",
:title => activity_item.content %>
<% end %>
</li>
And when i click on the actual micropost "title" i get the following error saying i've got "No route matches [GET] "/microposts". I'm sure this is probably an easy fix i'm missing, but I'm a beginner & I've been goin too long & my brain is fried.
What i basically need to have happen is when i click on the title of a micropost from my activity feed...I need it to go to the unique #show page of that micropost id.
Here are the models / controllers i believe are relevant. If i need to post anything else just let me know. I appreciate any and all help! Thanks!
static_pages_controller (the home page is where my activity feed shows up
class StaticPagesController < ApplicationController
def home
if signed_in?
#micropost = current_user.microposts.build
#activity_items = current_user.activity.paginate(:page => params[:page])
#friendactivity_items = current_user.friendactivity.paginate(:page => params[:page])
end
end
def help
end
def about
end
def contact
end
end
Microposts Controller
class MicropostsController < ApplicationController
before_filter :signed_in_user, :only => [:create, :destroy]
before_filter :correct_user, :only => :destroy
def index
end
def new
#micropost = current_user.microposts.build if signed_in?
end
def create
#micropost = current_user.microposts.build(params[:micropost])
if #micropost.save
flash[:success] = "Micropost created!"
redirect_to root_path
else
#activity_items = [ ]
render 'new'
end
end
def show
#micropost = Micropost.find(params[:id])
#users = #micropost.users.paginate(:page => params[:page])
end
def destroy
#micropost.destroy
redirect_to root_path
end
private
def correct_user
#micropost = current_user.microposts.find_by_id(params[:id])
redirect_to root_path if #micropost.nil?
end
end
Micropost Model
class Micropost < ActiveRecord::Base
attr_accessible :content, :title
belongs_to :user
validates :title, :presence => true, :length => { :maximum => 100 }
validates :content, :presence => true, :length => { :maximum => 220 }
validates :user_id, :presence => true
default_scope :order => 'microposts.created_at DESC'
# Returns Microposts from the users that the given user follows
def self.from_users_followed_by(user)
followed_user_ids = "SELECT followed_id FROM relationships
WHERE follower_id = :user_id"
where("user_id IN (#{followed_user_ids})",
:user_id => user.id)
end
end
I'm also adding now the routes.rb file and micropost model as requested
routes.rb
SampleApp::Application.routes.draw do
resources :users do
member do
get :following, :followers
end
end
resources :sessions, :only => [:new, :create, :destroy]
resources :microposts, :only => [:create, :destroy, :show]
resources :relationships, :only => [:create, :destroy]
# home page route
root :to => 'static_pages#home'
# signup route
match '/signup', :to => 'users#new'
match '/signin', :to => 'sessions#new'
match '/signout', :to => 'sessions#destroy', :via => :delete
# static pages routes
match '/help', :to => 'static_pages#help'
match '/about', :to => 'static_pages#about'
match '/contact', :to => 'static_pages#contact'
# create a micropost routes
match '/createamicropost', :to => 'microposts#new'
microposts Model as requested...Thanks!
class Micropost < ActiveRecord::Base
attr_accessible :content, :title
belongs_to :user
validates :title, :presence => true, :length => { :maximum => 100 }
validates :content, :presence => true, :length => { :maximum => 220 }
validates :user_id, :presence => true
default_scope :order => 'microposts.created_at DESC'
# Returns Microposts from the users that the given user follows
def self.from_users_followed_by(user)
followed_user_ids = "SELECT followed_id FROM relationships
WHERE follower_id = :user_id"
where("user_id IN (#{followed_user_ids})",
:user_id => user.id)
end
end
You are getting a routes error - No route matches [GET] "/microposts.
So, it's not related with code as such. Just declare the routes to microposts like this.
config/routes.rb
resources :microposts

undefined method `has_many' for Formtastic

I'm getting this error :
undefined method `has_many' for #<Formtastic::SemanticFormBuilder:0xb410d4c>
It work when I use it like this :
ActiveAdmin.register Ressource do
form do |f|
f.inputs do
f.input :offer_id, :as => :hidden
f.input :name
f.input :category, :include_blank => false, :collection => Category.order('place ASC').all, :member_label => :to_label
f.input :description, :input_html => {:class => 'editor'}
f.input :price
end
f.has_many :roles do |app_f|
app_f.inputs do
if not app_f.object.id.nil?
app_f.input :_destroy, :as => :boolean, :label => "Supprimer l'utilisateur du lot"
end
app_f.input :user, :member_label => :to_label, :label => 'Assigné le lot'
app_f.input :name, :include_blank => false
end
end
f.buttons
end
end
But it doesn't work in a partial, i need to call the has_many method by a different way or something else ?
ActiveAdmin extends formtastic with some useful helpers such as has_many (lib/active_admin/form_builder.rb in the activeadmin gem).
Unfortunately, these helpers are not available by default in your templates.
Here are two options:
If you don't need the extra has_many functionality (it looks like active_admin adds some javascript to make it easy to add a new record to the collection), then you can use stock formtastic. This example should work fine in the activeadmin file as well as in a partial:
ActiveAdmin.register Ressource do
form do |f|
# ...
f.inputs :for => :roles do |app_f|
# ...
app_f.input :name, :include_blank => false
end
f.buttons
end
end
Use the ActiveAdmin form builder explicitly:
<%= semantic_form_for [:admin, #resource], builder: ActiveAdmin::FormBuilder do |f| %>
<!-- ... -->
<%= f.has_many :teachers do |app_f| %>
<%= app_f.inputs do %>
<!-- ... -->
<% end %>
<% end %>
<%= f.buttons %>
<% end %>
I hope this helps.
There is a solution
form :html => {:multipart => true} do |f|
end
Or, if you want to use partial:
<%= active_admin_form_for [:admin, #resource] ,:html => {:multipart => true} do |f|%>
<% end %>

Can't create Custom inputs for some (Text, Booleans, ...) types, with SimpleForm

I can't figure out why this is not working as it should - or - I'm missing something important ?
Here's the list of the mapped types from simple_form / lib / simple_form / form_builder.rb:
map_type :text, :to => SimpleForm::Inputs::TextInput
map_type :file, :to => SimpleForm::Inputs::FileInput
map_type :string, :email, :search, :tel, :url, :to => SimpleForm::Inputs::StringInput
map_type :password, :to => SimpleForm::Inputs::PasswordInput
map_type :integer, :decimal, :float, :to => SimpleForm::Inputs::NumericInput
map_type :range, :to => SimpleForm::Inputs::RangeInput
map_type :select, :radio, :check_boxes, :to => SimpleForm::Inputs::CollectionInput
map_type :date, :time, :datetime, :to => SimpleForm::Inputs::DateTimeInput
map_type :country, :time_zone, :to => SimpleForm::Inputs::PriorityInput
map_type :boolean, :to => SimpleForm::Inputs::BooleanInput
First problem, I can extend StringInput class as:
#app/inputs/string_input.rb
class StringInput < SimpleForm::Inputs::StringInput
def input
if #builder.show?
content_tag(:p, #builder.object[attribute_name], :class => :show)
else
super
end
end
end
(I've extended the builder with a show? method to detect the context: action == 'show')
This is working most of the time but not when :as => :string is present :
<%= f.input :estimated_duration_rendered,
:as => :string,
:label => mt(:estimated_duration),
:hint => mt(:estimated_duration_hint),
:error => false,
:required => false,
:input_html => { :class => :digits_11, :placeholder => mt(:estimated_duration_placeholder), :value => format_duration(resource.estimated_duration, true) }
%>
Second problem, I can create custom inputs for StringInput, DateTimeInput, CollectionInput and BooleanInput but all the others are not working. For example:
#app/inputs/text_input.rb
class TextInput < SimpleForm::Inputs::TextInput
def input
if #builder.show?
"I will never show..."
else
super
end
end
end
Even if I have this helper in my form:
<%= f.input :description,
:label => mt(:description),
:hint => mt(:description_hint, :max => MyModel::DESC_MAX_LENGTH),
:input_html => { :class => :large, :rows => 8, :cols => 1, :maxlength => MyModel::DESC_MAX_LENGTH, :placeholder => mt(:description_placeholder) },
:error => false
%>
Of course, description has a text data type.
What Am I doing wrong ?
Thank you.
Fro
Well, to use this functionality you just need the 1.5.1 version of SimpleForm. :-)

Rails 3 Route error - "No Route Matches"

I've been reading over this resource as well as this post to try to understand Routes more (currently learning programming/Rails by doing) but am wondering how I can fix the error I'm getting, which is No route matches {:controller=>"profiles", :action=>"show"}.
I get the error working my way through a Rails 3 sign-up process using nested model forms. The sign-up process, as follows:
user = User.new
user.email = ""
user.password = ""
user.profile = Profile.new
user.profile.save
user.save
The sign-up process starts at the homepage with the following form:
<%= form_for :user, :url => signup_path, :html => {:id => 'homepage'} do |f| %>
<div>
...
</div>
<%= f.fields_for :profile do |f| %>
<% end %>
<% end %>
Then the process goes to fill in the profile, then redirect to the new User's profile after this form is completed:
<%= form_for :profile, :html => { :multipart => true } do |f| %>
<div>
...
</div>
<%= f.fields_for :user do |f| %>
<% end %>
<% end %>
I have accepts_nested_attributes_for :user and :profile in their respective models.
My rails server it gives me a bit more detail:
ActionController::RoutingError (No route matches {:controller=>"profile.save", :action=>"show"}):
app/controllers/profiles_controller.rb:15:in `create'
So in my ProfilesController in 'create':
def create
#profile = Profile.new(params[:profile])
if #profile.save
redirect_to profile_path, :notice => 'User successfully added.'
else
render :action => 'new'
end
end
Seems clear that the issue is in profile_path, so my Routes.rb:
post "/signup" => "profiles#create", :as => "signup"
match "skip/signup", :to => "info#signupskip"
match "skip/profiles/new", :to => "profiles#newskip"
root :to => "users#create"
Can anyone help shed light on what I'm doing wrong/missing in my Routes.rb file?
The redirect path should contain the specific profile to redirect to:
if #profile.save
redirect_to profile_path(#profile), :notice => 'User successfully added.'
else
.....
Also the routes should include this line:
get "/profiles/:id" => "profiles#show", as => "profile"