I'm having issues displaying values from a nested controller. I can update the field just fine, I just cannot see the values on the show page. I think it's an issue with Devise.
My user model is as follows:
class User < ActiveRecord::Base
has_one :page
accepts_nested_attributes_for :page, :allow_destroy => true
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me, :name
has_friendly_id :name, :use_slug => true, :strip_non_ascii => true
validates_presence_of :name
validates_uniqueness_of :name
validates_uniqueness_of :email, :case_sensitive => false
#creates a new page on user create if one doesn't exist
def after_initialize
self.build_page if self.page.nil?
end
end
My pages model:
class Page < ActiveRecord::Base
belongs_to :user
attr_accessible :tagline, :about, :email, :phone, :website, :blog, :user,
end
routes.rb
Ahoy::Application.routes.draw do
resources :users, :path => '/' do
resource :page
end
devise_for :users, :controllers => { :registrations => "registrations"}
get "home/index"
get "home/about"
root :to => "home#index"
end
In my users#show I have this:
<p>
<strong>Tagline</strong>
<%= #user.tagline %>
</p>
And I get a undefined method. Have also tried, #pages.tagline etc.
I didn't think I needed to amend my controller? Can you help?
The tagline method is defined in Page, so it should be #user.page.tagline
Related
I've published a sizable update to my heroku staging site and besides some saving issues (which I'll post in a separate question), I've noticed some weird things happening to my index url.
Projects are nested under users like such:
routes.rb
resources :users do
resources :projects do
get "cancel", :on => :member
post "cancel" => 'projects#cancel_save', :on => :member
get "rate_supplier", :on => :member
post "rate_supplier" => 'projects#rate_suppliers', :on => :member
end
end
Originally when I viewed a users projects it displayed correctly as
/users/2/projects
But now for some reason the url looks as follows:
users/2/projects.%23<Project::ActiveRecord_Associations_CollectionProxy:0x007fe577ab9820>
I'm not sure why the rest of that stuff is in the url?? And can't find anything online. Help!
UPDATE
The models looks as follows:
project.rb
class Project < ApplicationRecord
belongs_to :user, inverse_of: :projects
belongs_to :budget
belongs_to :industry
belongs_to :project_source
belongs_to :project_status
belongs_to :project_type, class_name: 'Project_type'
has_and_belongs_to_many :features, join_table: :projects_features
has_and_belongs_to_many :addons, join_table: :projects_addons
has_one :project_close_reason
accepts_nested_attributes_for :project_close_reason
has_one :supplier_rating
accepts_nested_attributes_for :supplier_rating
scope :open, -> {
where("project_status_id <=?", 8)
}
scope :closed, -> {
where("project_status_id >?", 8)
}
scope :cancelled, -> {
where("project_status_id =?", 10)
}
scope :completed, -> {
where("project_status_id =?", 9)
}
end
user.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable
validates :password, :presence => true,
:on => :create,
:format => {:with => /\A.*(?=.{8,})(?=.*\d)(?=.*[\#\#\$\%\^\&\+\=]).*\Z/ }
validates :email, :presence => true, :uniqueness => true
has_many :projects, inverse_of: :user
has_many :businesses, inverse_of: :user
accepts_nested_attributes_for :projects
def full_name
"#{last_name}, #{first_name}"
end
end
And here is the link:
<li class="<%= 'active' if params[:controller] == 'projects' %>">
<%= link_to user_projects_path(current_user, #projects) do %>
<i class="fa fa-list" aria-hidden="true"></i> Projects
<% end %>
</li>
And here is the index action in the projects controller
def index
#title = "Your Projects"
#projects = current_user.projects
end
The problem is link_to user_projects_path(current_user, #projects)
I'm figuring you're trying to render the index of projects for a single user.
You don't need to pass #projects in this case. You can simply remove the second argument.
The route you're trying to hit is /users/:user_id/projects.
Since this route only has one parameter (:user_id), you only need to pass one argument to link_to.
To link to individual project show pages, you can do this:
<% #projects.each do |project| %>
<%= link_to user_project_path(current_user, #projects) %>
<% end %>
Note the difference between user_projects_path, which takes only one argument, and user_project_path, which takes two.
this is my user model:
class User < Account
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
attr_accessible :email, :password, :password_confirmation, :remember_me
devise :database_authenticatable,
:ga_otp_authenticatable,
:yk_otp_authenticatable,
:registerable,
:confirmable,
:recoverable,
:trackable,
:validatable,
:lockable,
:timeoutable
# Setup accessible (or protected) attributes for your model
attr_accessible :password, :password_confirmation, :remember_me, :time_zone, :require_ga_otp, :require_yk_otp, :full_name, :address
attr_accessor :captcha,
:skip_captcha,
:new_password,
:new_password_confirmation,
:current_password
before_validation :generate_name,
:on => :create
has_many :trade_orders,
:dependent => :destroy
has_many :purchase_trades,
:class_name => "Trade",
:foreign_key => "buyer_id"
has_many :sale_trades,
:class_name => "Trade",
:foreign_key => "seller_id"
has_many :invoices,
:dependent => :destroy
has_many :yubikeys,
:dependent => :destroy
has_many :bank_accounts,
:dependent => :destroy
has_many :tickets,
:dependent => :destroy
#has_many :tickets,
# :dependent => :destroy
validates :email,
:uniqueness => true,
:presence => true
validate :captcha do
if captcha.nil? and new_record?
unless skip_captcha
errors[:captcha] << I18n.t("errors.answer_incorrect")
end
end
end
def captcha_checked!
self.captcha = true
end
def bitcoin_address
super or (generate_new_address && super)
end
def qr_code
if #qrcode.nil?
#qrcode = RQRCode::QRCode.new(bitcoin_address, :size => 6)
end
#qrcode
end
def confirm!
super
UserMailer.registration_confirmation(self).deliver
end
protected
def self.find_for_database_authentication(warden_conditions)
conditions = warden_conditions.dup
name = conditions.delete(:name)
where(conditions).where(["name = :value OR email = :value", { :value => name }]).first
end
def generate_name
self.name = "BF-U#{"%06d" % (rand * 10 ** 6).to_i}"
end
end
This is my account model:
class Account < ActiveRecord::Base
has_many :account_operations
has_many :used_currencies,
:dependent => :destroy
belongs_to :parent,
:class_name => 'Account'
validates :name,
:presence => true,
:uniqueness => true
# BigDecimal returned here
def balance(currency, options = {} )
account_operations.with_currency(currency).with_confirmations(options[:unconfirmed]).with_processed_active_deposits_only.map(&:amount).sum.round(5).abs
end
# Generates a new receiving address if it hasn't already been refreshed during the last hour
def generate_new_address
unless last_address_refresh && last_address_refresh > DateTime.now.advance(:hours => -1)
self.last_address_refresh = DateTime.now
self.bitcoin_address = Bitcoin::Client.instance.get_new_address(id.to_s)
save
end
end
def max_withdraw_for(currency)
Transfer.round_amount(self.balance(currency), currency)
end
def self.storage_account_for(currency)
account_name = "storage_for_#{currency.to_s.downcase}"
account = find_by_name(account_name)
if account
account
else
Account.create! do |a|
a.name = account_name
end
end
end
end
My problem is I am trying to input the password but it is not accepting password field. It is giving error that password cant be blank.
I have tried to create user manually. here it is giving error undefined method encrypted password.
how to solve this problem?
Try out this.....
Do you have the encrypted_password column on your model?
Yes
attr_accessible :email, :password, :password_confirmation, :remember_me, :encrypted_password
Just because it's attr_accessable doesn't mean the attribute exists, just means you can access it (if it did exist). Go into your rails console and run:
User.new.respond_to?(:encrypted_password=)
If that returns true you have the column in your model, if not you need to make sure you run the correct migrations.
User.new.respond_to?(:encrypted_password=) => false
I run rake db:migrate:reset and it work!!!
I'm trying to dynamically build a collection where each array contains a value from two separate tables.
The Models:
#/models/user.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable, :confirmable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :user_id, :email, :password, :password_confirmation, :remember_me,
:first_name, :last_name, :permanent_address, :permanent_city,
:permanent_state, :permanent_zip, :home_phone, :mobile_phone, :role,
:tenant_attributes, :rents_attributes
validates :email, :presence => true, :uniqueness => true
validates :first_name, :presence => true
validates :last_name, :presence => true
validates :permanent_address, :presence => true
validates :permanent_city, :presence => true
validates :permanent_zip, :presence => true
validates :first_name, :presence => true
validates :home_phone, :presence => true
has_one :app
has_one :tenant, :foreign_key => :users_id
has_many :rents
has_many :maints
accepts_nested_attributes_for :tenant
accepts_nested_attributes_for :rents, allow_destroy: true
end
#/models/tenant.rb
class Tenant < ActiveRecord::Base
belongs_to :users
belongs_to :units
attr_accessible :lease_begin, :lease_end, :rent_share, :users_id, :units_id
has_many :maints
end
The Helper Method (so far):
#/helpers/users_helper.rb
def tenants
tenants = Tenant.select([:id, ??? ])
tenants.map {|u| [u.???, u.id]}
end
The form field:
<%= f.input :tenant_id, :collection => tenants %>
Essentially what I'm trying to do is select the :id from the Tenants table and then the associated :first_name + :last_name (represented by "???" above) from the Users table to populate the collection arrays this would generate.
What's the best approach here?
If your helper is specifically used just for this input then I believe you have the correct thought on your query, in that you are concerned on retrieving just the required columns.
To retrieve tenants including attributes from their belongs_to :user relation, your helper definition needs to be updated to:
# app/helpers/users_helper.rb
def tenants
tenants = Tenant.joins(:user).select('tenants.id as tenant_id, users.first_name, users.last_name')
tenants.map { |u| [ [u.first_name, u.last_name].join(' '), u.tenant_id ]}
end
The tenants helper then returns a nested array of first_name and last_name joined with a space as one element and tenant_id as the second element array.
With the updated helper your view would be:
<%= f.select :tenant_id, :collection => tenants %>
Note the use of select helper here which is more suitable for this case.
I want to do STI in Rails.
class AbstractUser < ActiveRecord::Base
self.table_name = 'users'
belongs_to :organization, :inverse_of => :users
# reporter user
has_many :requests, :dependent => :destroy
# startup user
has_many :responses, :dependent => :destroy
has_many :startup_requests, :through => :responses, :source => :request
scope :reporters, where(:type => 'Reporter')
scope :startup_employees, where(:type => 'Startup')
scope :on_waitlist, where(:waitlist => true)
scope :not_on_waitlist, where(:waitlist => false)
end
require 'rfc822'
class User < AbstractUser
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :confirmable
validates :name, :presence => true
validates :surname, :presence => true
validates :title, :presence => true
validates :password, :presence => true, :length => { :minimum => 8 }
validates :email, :presence => true, :format => { :with => RFC822::EMAIL_REGEXP_WHOLE }
attr_accessible :name, :surname, :title, :organization,
:email, :password, :fullname
end
require 'rfc822'
class UserForAdmin < AbstractUser
validates :email, :presence => true, :format => { :with => RFC822::EMAIL_REGEXP_WHOLE }
validates :organization_id, :presence => true
attr_accessible :name, :surname, :title, :organization, :email,
:password, :fullname, :password_confirmation, :type,
:organization_id, :waitlist, :invitation_token
end
And there is some problem with these scopes.
Couldn't find UserForAdmin with id=7 [WHERE "users"."type" IN ('UserForAdmin') AND "users"."waitlist" = 'f']
I also tried to put these scopes in UserForAdmin instead of AbstractUser with the same result. I (probably) need scopes instead of custom methods, because I use them in ActiveAdmin. How can I solve this?
If you don't want to receive all users, you need to query with the base class. In a simpler example:
class Animal < ActiveRecord::Base
end
class Dog < Animal
end
class Cat < Animal
end
Dog.create
Cat.create
Animal.all
=> [dog, cat]
Dog.all
=> [dog]
Cat.all
=> [cat]
So, in your case, you'd want to:
AbstractUser.not_on_waitlist.find(params[:id])
If this user is a UserForAdmin you'll receive an object of class UserForAdmin. If it's just a user, you'll receive an object of class User
I am trying to update a user record using a formtastic nested form. Its structure is as ollows
User
Admin
Address
When I send the form to update details, while updating the address or admin record, the user_id(foreign key) gets set to NULL. This is the data that gets sent and it seems to be ok.
Parameters: {
"utf8"=>"✓", "authenticity_token"=>"some token",
"user"=>{
"id"=>"16",
"first_name"=>"User",
"last_name"=>"Name",
"email"=>"username#gmail.com",
"password"=>"[FILTERED]",
"password_confirmation"=>"[FILTERED]",
"address_attributes"=>{
"main_phone"=>"131231233",
"address1"=>"Address 1 Line",
"address2"=>"Address 2 Line",
"city"=>"Lansing",
"state"=>"Michigan",
"zip"=>"48823",
"user_id"=>"16"
},
"admin_attributes"=>{
"company_id"=>"2",
"user_id"=>"16"
},
"roles_mask"=>"1",
"user_id"=>"16"
},
"commit"=>"Update User Roles",
"company_id"=>"2",
"id"=>"16"
}
User Model
class User < ActiveRecord::Base
has_one :address, :dependent => :destroy, :inverse_of => :user
has_one :admin, :dependent => :destroy, :inverse_of => :user
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
attr_accessible :email, :password, :password_confirmation, :remember_me, :first_name, :last_name, :roles_mask, :terms_of_use,:id
attr_accessible :owner_attributes, :admin_attributes, :address_attributes, :client_attributes
accepts_nested_attributes_for :owner, :admin, :client, :address
end
Admin Model
class Admin < ActiveRecord::Base
belongs_to :company
belongs_to :user, :inverse_of => :admin
attr_accessible :company_id, :user_id
end
*Address Model
class Address < ActiveRecord::Base
belongs_to :user, :inverse_of => :address
attr_accessible :address1, :user_id, :address2, :city, :state, :zip, :main_phone, :cell_phone
end
Could you please help me with this. Thanks.
UPDATED with the model details. I removed the validation to keep it short.
Try to correct
accepts_nested_attributes_for :owner, :admin, :client, :address
in your User model with
accepts_nested_attributes_for :owner, :client
accepts_nested_attributes_for :admin, :address, :update_only => true