How can two user instances have the same account - ruby

In my rails app I want to create a shared account (later with different access levels). I want two instances of the User to have the same account.
My User Model has_many :accounts and my Account belongs_to :user
In the rails console when I do, e.g:
account = Account.first
account.user_id = [1, 2]
account.save
it returns true but when I check it again account.user_id = nil
How should I go on about it, then?
EDIT:
The Account Model:
class Account < ActiveRecord::Base
belongs_to :user
has_many :products
validates_presence_of :title
end
and the User model:
class User < ActiveRecord::Base
has_many :accounts
has_many :products, through: :accounts
accepts_nested_attributes_for :accounts
validates_presence_of :name
before_save do
self.email = email.downcase unless :guest?
end
validates :name, presence: true, length: { maximum: 50 }, unless: :guest?
end
EDIT 2:
I've updated the models relationship so the new Account model is:
class Account < ActiveRecord::Base
has_and_belongs_to_many :users
validates_presence_of :title
end
and the new User model is:
class User < ActiveRecord::Base
has_and_belongs_to_many :accounts
belongs_to :account
has_many :products, through: :accounts
accepts_nested_attributes_for :accounts
validates_presence_of :name
before_save do
self.email = email.downcase unless :guest?
end
validates :name, presence: true, length: { maximum: 50 }, unless: :guest?
end
I also created a new migration, a accounts_users table
class CreateAccountsUsersJoinTable < ActiveRecord::Migration
def change
create_join_table :users, :accounts do |t|
## Not sure if this is necessary
##t.index [:user_id, :account_id]
##t.index [:account_id, :user_id]
t.belongs_to :user
t.belongs_to :account
end
end
end
Still I can't have a account with multiple users

Related

Validate uniqueness nested model params

I have three models:
class User < ActiveRecord::Base
has_many :user_countries
accepts_nested_attributes_for :user_countries, reject_if: :all_blank
validate :user_countries
end
class UserCountry < ActiveRecord::Base
belongs_to :user
belongs_to :country
end
class Country < ActiveRecord::Base
has_many :user_countries
has_many :users, :through => :user_countries
end
In a the user creation form I can create user_countries too. How I can validate in server the uniqueness of country_id in user_countries. A user has many countries: France, United State... but not for example: France and France.
I've added this to user_countries.. but it don't work:
validates :user_id, uniqueness: {scope: :country_id, allow_blank: false}
Try this in the user_country model.
class UserCountry < ActiveRecord::Base
belongs_to :user
belongs_to :country
validates_uniqueness_of :user_id, scope: :country_id, allow_blank: false
end
Also, you need to create a migration like below to add unique indexes on database level.
add_index :user_countries, [ :user_id, :country_id ], :unique => true

Rails 4 dynamic form nested attributes without hidden input

Previously I asked a question about building an attendance list getting the students and building a check list to mark attendance and came up with this.
def new
#attendance_list = #classroom.attendance_lists.new
#attendance_list.attendances = #classroom.student_ids.map do |student_id|
#attendance_list.attendances.build(student_id: student_id)
end
end
def create
#attendance_list = #classroom.attendance_lists.new(attendance_list_params)
#attendance_list.classroom_id = params[:classroom_id]
respond_to do |format|
end
params
params.require(:attendance_list)
.permit(:post_date, :remark,
attendances_attributes: [:student_id, :attended, :remarks ])
with simple fields
= simple_form_for [#school, #classroom, #attendance_list] do |f|
= f.input :post_date
= f.input :remark
= f.simple_fields_for :attendances do |g|
** you see i needed a hidden student_id **
= g.input :student_id, as: :hidden
......
model
class AttendanceList < ActiveRecord::Base
belongs_to :classroom
has_many :attendances
has_many :students, :through => :attendances
accepts_nested_attributes_for :attendances
end
class Attendance < ActiveRecord::Base
belongs_to :student
belongs_to :attendance_list
end
class Classroom < ActiveRecord::Base
belongs_to :school
has_and_belongs_to_many :students
has_many :attendance_lists
validates :class_name, presence: true
end
how do I do without the hidden input because this line doesn't seem to work.
build(student_id: student_id)
class AttendanceList < ActiveRecord::Base
belongs_to :classroom
has_many :attendances
has_many :students, :through => :attendances
accepts_nested_attributes_for :attendances
end
class Attendance < ActiveRecord::Base
belongs_to :student
belongs_to :attendance_list
end
class Classroom < ActiveRecord::Base
belongs_to :school
has_and_belongs_to_many :students
has_many :attendance_lists
validates :class_name, presence: true
end
class Student < ActiveRecord::Base
has_many :attendances
has_many :attendance_lists, :through => :attendances
end
view file
= simple_form_for #student do |f|
= f.simple_fields_for :attendances do |g|
** your code **

Papertrail undefined method `klass' for nil:NilClass

I have this revert method in my controller
def revert
version = PaperTrail::Version.find(params[:id])
if version.reify
version.reify(:has_many=>true).save!
else
version.item.destroy
end
share_type = ShareType.find(params[:share_type_id])
redirect_to :back
end
I am getting error of undefined method `klass' for nil:NilClass on
version.reify(:has_many=>true).save!
but when I try
version.reify.save!
everything become fine what am I doing wrong I am using revert method for another resource with
def revert
version = PaperTrail::Version.find(params[:id])
if version.reify
version.reify(has_many: true).save!
else
version.item.destroy
end
company = Company.find_by_slug(params[:company_id])
redirect_to :back
end
This works fine with out any error.
here are my models for both resources
class ShareType < ActiveRecord::Base
has_paper_trail
belongs_to :company
has_many :issue_shares, dependent: :destroy
has_many :users, through: :shares
validates :company, :code, :name, :reason, :effective_date, presence: true
before_save :convert_new_line_to_html
def convert_new_line_to_html
self.description.to_s.gsub!(/\r\n?/, "<br>")
end
end
and for company
class Company < ActiveRecord::Base
extend FriendlyId
friendly_id :slug_candidates, use: :slugged
has_many :user_companies, dependent: :destroy
has_many :users, through: :user_companies
has_many :advisor_invitations
has_many :company_advisors
has_many :advisors, through: :company_advisors
belongs_to :created_by, class_name: "User", foreign_key: "user_id"
has_many :share_types, dependent: :destroy
validates :user_id, :name,:company_no,:company_type,:registered_office, :principle_place, presence: true
validates_uniqueness_of :name, :company_no
validates_presence_of :register_address_occupier, :if => lambda { |o| !o.occupied_by_company }
has_paper_trail
def slug_candidates
[
:name,
[:name, :company_type],
[:name, :company_type, :company_no],
]
end
def should_generate_new_friendly_id?
slug.blank? || name_changed?
end
def is_admin?(user)
!user_companies.where("user_id=? AND role=?",user.id, 0).empty?
end
def share_holder?(user)
shares = Share.includes(issue_share:[:share_type]).where("share_types.company_id=? AND shares.user_id=?", id, user.id).references(:share_types)
!shares.empty?
end
def is_director?(user)
!user_companies.where("user_id=? AND role=?",user.id, 1).empty?
end
def is_advisor?(user)
!advisors.where("user_id=?",user.id).empty?
end
end
I solved the problem there is an association
has_many :users, through: :shares
in share_types while I do not have
has_many :shares
so I need to remove this line
has_many :users, through: :shares
which I do not need this solved my problem.

Configuring Categorizations With Rails 3

I want to be able to assign categories to my user's (up to 2, allow for 1). I want any posts by this user to be assigned only one category from the same list of categories (which are referred to as profession(s) for my app).
Currently, I have configured it so that I can assign 1 to each, with simple belongs_to and has_many associations between the user, post, and profession models. This works fine for the post, because it only requires 1 profession assignment, but for the user it is limiting the ability for 2.
The view for the user has two drop-down lists, populated by the items in the profession. I can select two different professions, but only one retains the value for the profession, where I would like it to keep both or only accept one if only one has been selected. My major limitation is that in the user database, there is only one profession column that refers to the profession_id. I can't duplicate the profession column, so how do I set it up so that a second profession field can be added?
Or, how should I change my database design and models to accomplish this?
user.rb:
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
attr_accessible :email,
:password,
:password_confirmation,
:remember_me,
:first_name,
:last_name,
:profile_name,
:full_bio,
:mini_bio,
:current_password,
:photo,
:profession_id
attr_accessor :current_password
validates :first_name, :last_name, :profile_name, presence: true
validates :profile_name, uniqueness: true,
format: {
with: /^[a-zA-Z0-9_-]+$/
}
has_many :posts
belongs_to :profession
has_attached_file :photo,
:default_url => 'default.png'
def full_name
first_name + " " + last_name
end
end
post.rb:
class Post < ActiveRecord::Base
attr_accessible :content, :name, :user_id, :profession_id
belongs_to :user
belongs_to :profession
validates :content, presence: true,
length: { minimum: 2 }
validates :name, presence: true,
length: { minimum: 2 }
validates :user_id, presence: true
end
profession.rb:
class Profession < ActiveRecord::Base
attr_accessible :name
has_many :posts
has_many :users
end
In this case, a has_many :through association for your Users and Professions may work best. With an additional model of something like "Specialty", you can model this relationship as follows:
class User < ActiveRecord::Base
has_many :specialties
has_many :professions, :through => :specialties
end
class Profession < ActiveRecord::Base
has_many :specialties
has_many :users, :through => :specialties
end
class Specialty < ActiveRecord::Base
belongs_to :user
belongs_to :profession
end
You can then use the nested_form gem in your view to accept the professions associated with that user.

has_many :through child and parent validations

I have a rails 3.0
has_many :X, :through => :something set up and i have a custom validator that does some custom validation on some complicated logic. I want to when you add anything to this many to many relationship both models are valid?
Project Class:
class Project < ActiveRecord::Base
has_many :assignments
has_many :users, :through => :assignments
validates :name, :presence => true
end
Assignment:
class Assignment < ActiveRecord::Base
belongs_to :project
belongs_to :user
end
User class with custom validator:
class MyCustomValidator < ActiveModel::Validator
def validate( record )
if record.projects.length > 3
record.errors[:over_worked] = "you have to many projects!"
end
end
end
class User < ActiveRecord::Base
has_many :assignments
has_many :projects, :through => :assignments
validates :name, :presence => true
validates_with MyCustomValidator
end
What i really want to do is prevent each model from invalidating the other so to say
prevent
my_user.projects << fourth_project
and
my_project.users << user_with_four_projects_already
from happening. Right now it allows the assignment and just the user becomes invalid.
class Project < ActiveRecord::Base
has_many :assignments
has_many :users, :through => :assignments
validates :name, :presence => true
validates_associated :users
end
According to the docs, users must already be assigned to Projects in order to be validated. So:
my_user.projects << fourth_project
would occur, then projects would validate the user and see that it is indeed invalid, making the project invalid as well as in the inverse example.

Resources