Papertrail undefined method `klass' for nil:NilClass - ruby

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.

Related

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 **

How can two user instances have the same account

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

Update multiple records using one form

I have a following situation: user has multiple assets and each asset has one asset_detail record.
Models:
class User < ActiveRecord::Base
has_many :assets
end
class Asset < ActiveRecord::Base
has_one :asset_detail
belongs_to :user
accepts_nested_attributes_for :asset_detail,
:allow_destroy => false
attr_accessible # ...
end
class AssetDetail < ActiveRecord::Base
belongs_to :asset
attr_accessible # ...
end
Controller actions:
def edit
#user = current_user
#assets = Asset.all
end
def update
#user = current_user
#user.update_attributes(params["user"])
end
View:
= form_for #user, url: 'update action url' do |f|
= f.fields_for :assets do |ff|
= ff.text_field :title
= ff.fields_for :asset_detail do |fff|
= fff.text_field :value
The problem is that all the form fields are populated properly but i'm not able to save them. The form is sent without any error but the data is not updated.
I think your models should look like this:
class User < ActiveRecord::Base
attr_accessible :assets_attributes #...
has_many :assets
accepts_nested_attributes_for :assets_attributes
end
class Asset < ActiveRecord::Base
attr_accessible :asset_detail_attrbutes # ...
has_one :asset_detail
belongs_to :user
accepts_nested_attributes_for :asset_detail_attributes,
:allow_destroy => false
end
the reason being, you need to be able to set the attributes via the attributes hash passed to each model. HTH!

How do I Query Polymorphic Comments when commentables can belong to another commentable?

So I'm trying to do a relatively advanced query on a polymorphic model. I have the following models:
class Project < ActiveRecord::Base
has_many :project_stakeholders, :dependent => :destroy
has_many :features, :dependent => :destroy
has_many :iterations, :dependent => :destroy
has_many :comments, :as => :commentable, :dependent => :destroy
end
class ProjectStakeholder < ActiveRecord::Base
belongs_to :project
has_many :comments, :as => :commentable, :dependent => :destroy
end
class Feature < ActiveRecord::Base
belongs_to :project
has_many :comments, :as => :commentable, :dependent => :destroy
end
class Iteration < ActiveRecord::Base
belongs_to :project
has_many :comments, :as => :commentable, :dependent => :destroy
end
class User < ActiveRecord::Base
has_many :comments, :dependent => :destroy
end
class Comment < ActiveRecord::Base
belongs_to :commentable, :polymorphic => true
belongs_to :created_by, :class_name => 'User'
end
I'm trying to find the current_user's comments for a particular project (project.comments, project.features.comments, project.iterations.comments, project.project_stakeholder.comments) and sort them in created_at descending order.
The best I have come up with is:
Class Project < ActiveRecord::Base
def all_comments_for_user(user)
Comment.where(:created_by_id => user.id).select { |c| c.commentable.attributes.has_key?('project_id') }.select { |c| c.commentable.project == self } | comments.where(:created_by_id => user)
end
end
But this doesn't address the descending create_at sequence.
Class Project < ActiveRecord::Base
def all_comments_for_user(user)
Comment.where(:created_by_id => user.id).order('created_at DESC').select { |c| c.commentable.attributes.has_key?('project_id') }.select { |c| c.commentable.project == self } | comments.where(:created_by_id => user)
end
end
Does this work ? I just added order('created_at DESC')

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