Note everything works in local enviromnment
This is the code
PublicActivity::ORM::ActiveRecord::Activity.class_eval do
attr_accessible :reference_type, :reference_id
has_many :notifications, :dependent => :destroy_all
has_many :users, :through => :notifications
end
This is with the public_activity gem
the error is
/app/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.13/lib/active_record/associations/builder/has_many.rb:20:in `configure_dependency': The :dependent option expects either :destroy, :delete_all, :nullify or :restrict (:destroy_all) (ArgumentError)
if it expects :destroy_all and I wrote :destroy_all and it works locally.. then what is going on here?
To the source!
unless options[:dependent].in?([:destroy, :delete_all, :nullify, :restrict])
raise ArgumentError, "The :dependent option expects either :destroy, :delete_all, " \
":nullify or :restrict (#{options[:dependent].inspect})"
end
So in that error message, the part that says (:destroy_all) is just telling you what you provided; the list of what it was expecting is before that. You probably want :destroy instead. Can't say why it worked locally and not on Heroku; might be some sort of gem version problem.
Related
I am facing a weird behaviour. This is my scenario.
class Message < ActiveRecord::Base
belongs_to :user, :foreign_key => "from_user_id"
has_many :message_recipients, :include => [:user], :dependent => :destroy
has_many :recipients, :through => :message_recipients, :source => :user
end
class MessageRecipient < ActiveRecord::Base
belongs_to :user
belongs_to :message, :include => :message_recipients
end
class User < ActiveRecord::Base
acts_as_paranoid
has_many :message_recipients
end
I am creating a new message and pushing value to its recipients.
#message=Message.new(:body => "Hi",:from_user_id => session[:user])
#message.recipients.push(User.find(params[:message_recipient_id]))
#message.save
The above operation saves the record in message correctly but fails to trigger the message_recipient record. But if i perform the above code removing the acts_as_paranoid gem, then it works fine. Is there any work around to solve this issue?
Solution 1:
Instead of calling new on Message model we can use create on Message model. So the record will be created and then i can push the data inside the recipients.Its like creating parent record and using its id i am creating child record. So there is no need for trigerring and it works fine.
Suggestions are welcome.
It works fine with rails 3.2.12 but fails with rails 3.2.13. I am confused with this behaviour.
I have model associations as follows:
class Group < ActiveRecord::Base
has_many :group_links, :dependent => :destroy
end
class GroupLink < ActiveRecord::Base
belongs_to :group
validates_presence_of :group_id
validates_presence_of :url, :message => "We need a url to create a link"
validates_uniqueness_of :url, :message => "A link with this url already exists"
validates_presence_of :text, :message => "We need a text to create a link"
validates_uniqueness_of :text, :message => "A link with this text already exists"
end
I want it to work like in each group the group links should be unique. However the way it works is, it throws the validations errors even if some other group has thins group link.
what am i doing wrong?
thanks in advance,
I used :scope => :group_id for my uniqueness validations to get this to work
'm trying to tweek Spree to my needs and I've hit a bump. I'll try to explain as best as I can without pasting too much code, 'cause Spree has quite a lot of it...
For starters. I've extended OptionType like this
Spree::OptionType.class_eval do
PRODUCT_TYPES = SuperMap.new( [:default, 0],
[:vehicle_bonnet, 1],
[:vehicle_images, 2])
super_mapped_attr :product_type, PRODUCT_TYPES
attr_accessible :product_type
end
I want to check in the show view of the ProductsController what sort of product_type I'm dealing with, like this:
<% if #product.option_types.product_type_key == :vehicle_bonnet %>
...
<% end %>
and I get undefined method ``product_type_key'. This method should be available thanks to SuperMap.
Now, the Product and OptionType has a bit strange association (for me at least).
module Spree
class Product < ActiveRecord::Base
has_many :product_option_types, :dependent => :destroy
has_many :option_types, :through => :product_option_types
end
end
so far seems to be ok.
module Spree
class ProductOptionType < ActiveRecord::Base
belongs_to :product
belongs_to :option_type
acts_as_list :scope => :product
end
end
and now comes the weird part:
module Spree
class OptionType < ActiveRecord::Base
has_many :option_values, :order => :position, :dependent => :destroy
has_many :product_option_types, :dependent => :destroy
has_and_belongs_to_many :prototypes, :join_table => 'spree_option_types_prototypes'
attr_accessible :name, :presentation, :option_values_attributes
validates :name, :presentation, :presence => true
default_scope :order => "#{self.table_name}.position"
accepts_nested_attributes_for :option_values, :reject_if => lambda { |ov| ov[:name].blank? || ov[:presentation].blank? }, :allow_destroy => true
end
end
this is actually the whole OptionType model. What suprises me it doesn't have has_many :products, through: :product_option_types. I've tried to add this line to my extension, but didn't help. I've tried few other thing of course, but it just made such a mess I went back to this version, since I think it shows best what I'm trying to achieve. What am I missing?
EDIT (solved, I should hope so...):
Turned out that in the Product model there was an alias alias :options :product_option_types, which was (imho) in the wrong place, because somewhere in the middle of a quite a long model (I should think it should have been somewhere closer to the has_many, but that's just me).
Further more, the options turned out to be an array, no that shocking come to think of it. So, what I did is extended the product model, added a method, where I'm checking the product_type_key, like so:
def type_of_product?(type)
options.each do |opts|
if opts.option_type.product_type_key == type
return true
end
end
false
end
Not the prettiest method, but it works as I expect it to...
lets say I have two models
class User < ActiveRecord::Base
has_many :friendships, :dependent => :destroy
has_many :followings, :through => :friendships, :foreign_key => "followed_id"
end
class Friendship < ActiveRecord::Base
belongs_to :user
belongs_to :following, :class_name => "User", :foreign_key => "followed_id"
end
now in my user_spec.rb I have this test
it "should delete all friendships after user gets destroyed" do
#user.destroy
[#friendship].each do |friendship|
lambda do
Friendship.find(friendship)
end.should raise_error(ActiveRecord::RecordNotFound)
end
end
is this the right place to test the :dependent => :destroy relation or does this belong inside the friendship_spec.rb or doesn't it matter in which of the two specs I test this?
You might consider using shoulda_matchers to test your associations:
# user_spec.rb
it { should have_many(:friendships).dependent(:destroy) }
# friendship_spec.rb
it { should belong_to(:user) }
Having each model test its own associations is the best approach IMHO.
This sort of thing is sometimes a matter of taste, but I think the spec for User is probably the best place to test this. The method you're calling to start the test is a method on User, so it makes sense to test it along the other tests for User as well.
I have a method that works locally on my machine but it fails in Heroku. Heroku logs say:
NoMethodError (undefined method `events' for nil:NilClass)
I have used heroku console for an equivalent of this method and it works so there is data that supports it. The method is:
def index
#events = current_user.school.events
end
I am using Devise which I believe gives me the current_user method. The equivalent, a = User.first.school.events yields the true instance value with data. The User.first yields correct data.
Here are my models:
class School < ActiveRecord::Base
#validates_presence_of :name
has_many :events, :dependent => :destroy
has_many :users, :dependent => :destroy
belongs_to :user
belongs_to :event
def self.fetch_for_name(_name)
school = self.new(:name => _name)
end
end
class User < ActiveRecord::Base
belongs_to :school
rolify
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
attr_accessible :name, :email, :password, :password_confirmation, :remember_me
end
class Event < ActiveRecord::Base
belongs_to :school
end
It would be like me if I overlooked some simple, basic thing but if I can do this correctly in Heroku console, why would this method break. Another unrelated page works correctly on Heroku.
current_user is the user that is logged in. It doesn't necessarily mean User.first. This should be the same locally as on Heroku. If you're having trouble figuring out what user is logged in you can add this to your application controller
before_filter :debug
def debug
Rails.logger.info("Current User is: #{current_user.inspect}")
end
And then view the output with $ heroku logs --tail It should show you the current value of the current_user. At the end of the day what #thesis said is correct, you have a user that does not have a school associated with it.