Acts_as_paranoid and validation - ruby-on-rails

Using rails 3 and acts_as_paranoid. I want to make sure that every task has a comment.
How can I bypass this one validation (check_if_notes) if mark_completed_and_msg is called?
EDIT - Is this the right way?
task.rb
has_one :comment, :as => :commentable
attr_accessor :force_task
# original was - before_update, :check_if_notes
validate :check_if_notes, :on => :update, :unless => proc { |a| a.force_task }
def mark_completed_and_msg(user_id, msg)
Comment.create!(:commentable_type => self.class, :commentable_id => self.id, :content => msg )
self.update_attributes(:completed_by => user_id, :deleted_at => Time.now, :force_task => true)
end
def check_if_notes
if self.comment.blank? || self.comment.content.blank? || self.comment.content.scan(/[\w-]+/).size <= 2
saved = false
self.comment.errors[:content] << "You must have a comment and more than 3 words."
raise ActiveRecord::Rollback
end
end

I think you meant using == in your Proc.
:unless => proc { |a| a[:force_task] == true }
You can also use
:unless => proc { |a| a.force_task? }

Related

How to fix undefined method in nested models? post/create in Rails app

Beginner programmer, probably getting over my head with multiple models, but your help would be greatly appreciated. Subjects have many pages, pages have many sections, sections have section edits. Been searching for hours for solution, just haven't found anything that works. Why am I getting this error? I've clearly overlooked something... Thanks!
Error:
NoMethodError in SectionsController#create
NoMethodError (undefined method `subject_id' for #<Section:0x007fe2efe24a80>
Did you mean? object_id):
app/controllers/sections_controller.rb:24:in `create'
sections_controller.rb
class SectionsController < ApplicationController
layout 'admin'
before_action :confirm_logged_in
before_action :find_page
before_action :find_pages, :only => [:new, :create, :edit, :update]
before_action :set_section_count, :only => [:new, :create, :edit, :update]
...
def create
#section = Section.new(section_params)
#section.page = #page
if #section.save
flash[:notice] = "Section created successfully."
redirect_to(sections_path(:page_id => #page.id))
else
render('new')
end
end
...
private
def section_params
params.require(:section).permit(:name, :position, :visible, :content_type, :content)
end
def find_page
#page = Page.find(params[:page_id])
end
def set_section_count
#section_count = #page.sections.count
if params[:action] == 'new' || params[:action] == 'create'
#section_count += 1
end
end
with error originating from line in 'create':
if #section.save
routes.rb
Rails.application.routes.draw do
root :to => 'public#index'
get 'show/:permalink', :to => 'public#show', :as => 'public_show'
get 'admin', :to => 'access#menu'
get 'access/menu'
get 'access/login'
post 'access/attempt_login'
get 'access/logout'
resources :admin_users, :except => [:show] do
member do
get :delete
end
end
resources :subjects do
member do
get :delete
end
end
resources :pages do
member do
get :delete
end
end
resources :sections do
member do
get :delete
end
end
section.rb
class Section < ApplicationRecord
acts_as_list :scope => :subject
belongs_to :page
has_many :section_edits
has_many :admin_users, :through => :section_edits
scope :visible, lambda { where(:visible => true) }
scope :invisible, lambda { where(:visible => false) }
scope :sorted, lambda { order("position ASC") }
scope :newest_first, lambda { order("created_at DESC") }
CONTENT_TYPES = ['text', 'HTML']
validates_presence_of :name
validates_length_of :name, :maximum => 255
validates_inclusion_of :content_type, :in => CONTENT_TYPES,
:message => "must be one of: #{CONTENT_TYPES.join(', ')}"
validates_presence_of :content
end
page.rb
class Page < ApplicationRecord
acts_as_list :scope => :subject
belongs_to :subject, { :optional => false }
has_many :sections
has_and_belongs_to_many :admin_users
scope :visible, lambda { where(:visible => true) }
scope :invisible, lambda { where(:visible => false) }
scope :sorted, lambda { order("position ASC") }
scope :newest_first, lambda { order("created_at DESC") }
validates_presence_of :name
validates_length_of :name, :maximum => 255
validates_presence_of :permalink
validates_length_of :permalink, :within => 3..255
validates_uniqueness_of :permalink
end
subject.rb
class Subject < ApplicationRecord
acts_as_list
has_many :pages
scope :visible, lambda { where(:visible => true) }
scope :invisible, lambda { where(:visible => false) }
scope :sorted, lambda { order("position ASC") }
scope :newest_first, lambda { order("created_at DESC") }
scope :search, lambda {|query| where(["name LIKE ?", "%#{query}%"]) }
validates_presence_of :name
validates_length_of :name, :maximum => 255
end
Rest of my code
https://github.com/danwernstrom13/simple_cms
Let me know if I can provide any more context or code... Your assistance greatly appreciated!
You should remove this line from Section model:
acts_as_list :scope => :subject
because Section does not belong to Subject.
This would be correct:
acts_as_list :scope => :page

#<ActiveRecord::Associations::CollectionProxy []> in Rails

I am facing this error while running my application:
<ActiveRecord::Associations::CollectionProxy []>
I am able to store reports but couldn't store icons. It is storing fine in Rails 3.2.13, but raising this issue in Rails 4.2.6.
report.rb:
class Report < ActiveRecord::Base
belongs_to :user
has_many :icons, -> { order 'position_id ASC'}
accepts_nested_attributes_for :icons, :reject_if => lambda { |a| a[:icon].blank? }, :allow_destroy => true
end
icon.rb:
class Icon < ActiveRecord::Base
belongs_to :report
end
reports_controller:
def new
#report = #user.reports.new({
:background_color => Rails.application.config.custom.accounts.send(#user.account.name).colors.background,
:text_color => Rails.application.config.custom.accounts.send(#user.account.name).colors.commentary,
:button_color => Rails.application.config.custom.accounts.send(#user.account.name).colors.button
})
3.times { #report.icons.build }
end
def create
respond_to do |format|
if #report.save
format.json { render :json => { :success => true, :user_id => #user.id, :report_id => #report.id, :report_title => #report.title, :icon_array => #report.icons, :redirect => user_report_url(current_user, #report.id) } }
else
format.json { render :json => { :success => false } }
end
end
end
I am able to store reports but icons are not stored. Please help
I think you might have missed icon attributes in the strong parameters.

How to use AREL eq() method in a where with joined data

I currently have this scope:
class User
has_many :inbox_messages, :through => :message_users do
def unread
published.where(:message_users => { :sender => false, :trash => false , :deleted => false}).where(MessageUser.arel_table[:read_at].not_eq(nil))
end
end
end
And it's working. But I was wondering if there is way to merge the second where into the first one.
If I understand your code correctly, you should be able to do that with
published.where(:message_users => { :sender => false, :trash => false , :deleted => false, :read_at => nil })

Why are the results loading from the db, instead of cache?

When I run:
IpPermission.blacklist.pluck(:ip)
I get the results:
=> ["127.0.0.11012q", "50.36.46.48"]
If I manually change any of the rows in the ip_permissions table, and run IpPermission.blacklist.pluck(:ip) again. It displays the updated results. Shouldn't it load the results from cache and not directly from the db?
My model looks like:
class IpPermission < ActiveRecord::Base
validates_presence_of :ip, :note, :category
validates_uniqueness_of :ip, :scope => [:category]
validates :category, :inclusion => { :in => ['whitelist', 'blacklist'] }
def self.whitelist
Rails.cache.fetch('whitelist', :expires_in => 1.month) { self.where(:category => 'whitelist') }
end
def self.blacklist
Rails.cache.fetch('blacklist', :expires_in => 1.month) { self.where(:category => 'blacklist') }
end
end
I think this should solve our problem:
Change this
def self.whitelist
Rails.cache.fetch('whitelist', :expires_in => 1.month) { self.where(:category => 'whitelist') }
end
def self.blacklist
Rails.cache.fetch('blacklist', :expires_in => 1.month) { self.where(:category => 'blacklist') }
end
to this
def self.whitelist
Rails.cache.fetch('whitelist', :expires_in => 1.month) { self.where(:category => 'whitelist').all }
end
def self.blacklist
Rails.cache.fetch('blacklist', :expires_in => 1.month) { self.where(:category => 'blacklist').all }
end
The where does not make the actual query, if you put .all then you make the query, so you are not storing the data but you just storing the query

Adding an rails activerecord association within a loop

I want to add a has_many through association to a activerecord model class for each symbol in an array. for example
PeopleOrganisation::ROLES.each do |role|
has_many role.to_s.pluralize.to_sym, :through => :people_organisations, :source => :person,
:conditions => "people_organisations.role = '#{role.to_s}'" do
def << (object)
PeopleOrganisation.send(:with_scope, :create => {:role => **role**}) { self.concat object }
end
end
end
everything works fine except for the reference to the role variable inside the method def. This is because the method def is not a closure. Is there a way of achieving what I want?
Try this:
PeopleOrganisation::ROLES.each do |role|
has_many(role.to_s.pluralize.to_sym,
:through => :people_organisations, :source => :person,
:conditions => ["people_organisations.role = ?", role]
) do
define_method("<<") do |object|
PeopleOrganisation.send(:with_scope, :create => {:role => role}) {
self.concat object
}
end
end
end
Instead of defining method using def you can try define_method method:
PeopleOrganisation::ROLES.each do |role|
has_many role.to_s.pluralize.to_sym, :through => :people_organisations, :source => :person,
:conditions => "people_organisations.role = '#{role.to_s}'" do
define_method(:<<) do |object|
PeopleOrganisation.send(:with_scope, :create => {:role => role}) { self.concat object }
end
end
end

Resources