RoR: Stack level too deep with after create method? - ruby-on-rails

I have the the following after create method in my record model that keeps throwing an Stack level too deep error every time i try creating a new record:
class record
has_many :authorizations
has_many :roles, :through => :authorizations, :dependent => :destroy, :primary_key => :record_secondary_id
after_create :new_record
def create_roles
self.roles.create :name => "#{self.record_title} edit", :record_id => self.id, :edit => true, :review => false
self.roles.create :name => "#{self.record_title} review", :record_id => self.id, :edit => false, :review => true
end
def set_secondary_id
self.update_attribute :record_secondary_id, self.id
end
def new_record
if self.record_secondary_id.blank?
set_secondary_id
create_roles
end
end
end
end

You are having infinite recursion between create record and create_roles.
You need to create role with the record itself instead of callback.
It will be easy as you are using has_many through relationship.
Edited:
In your controller,
#record = Record.new(params[:record])
#role1 = Role.new('some_params')
#role2 = Role.new('some_params')
#record.roles = [#role1, #role2]
#record.save

I think your problem might be coming from the following call:
has_many :authorizations
has_many :roles, :through => :authorizations, :dependent => :destroy, :primary_key => :record_secondary_id
change that to:
has_many :authorizations, :dependent => :destroy, :primary_key => :record_secondary_id
has_many :roles, :through => :authorizations
that should fix your problem.

Related

How not get current_user

i'm breaking my head to get the user of this situation:
a conversation model:
has_many :conversation_participants, :dependent => :destroy
has_many :users,
:through => :conversation_participants
has_many :messages, :dependent => :destroy
has_one :display_message,
:class_name => 'Message',
:order => 'created_at DESC'
def participants(options={})
if options[:not].is_a? User
users - [options[:not]]
else
users
end
end
and conversation_participants:
belongs_to :user
belongs_to :conversation
attr_accessible :user_id
on a conversation helper:
def self_or_other
#conversation.conversation_participants.find_by_user_id(:not => current_user)
end
please, someone could clear me how to get the other user inside conversation_participants model?
I believe like follows:
#conversation.conversation_participants.where.not(user_id: current_user.id).first

Rails 4 new record from different model

I am currently working on a rails based application to manage orders. (Rails 4.1.5 and ActiveAdmin)
I have these models:
class Customer < ActiveRecord::Base
has_many :estimates
has_many :orders
accepts_nested_attributes_for :estimates, :allow_destroy => true
accepts_nested_attributes_for :orders, :allow_destroy => true
end
class Order < ActiveRecord::Base
belongs_to :customer
has_many :line_items, as: :cartable
accepts_nested_attributes_for :line_items, :allow_destroy => true
end
class Estimate < ActiveRecord::Base
belongs_to :customer
has_many :line_items, as: :cartable
accepts_nested_attributes_for :line_items, :allow_destroy => true
end
What I want to do is to create a new Order based on the Estimate record. The things work if I create a new order and show the edit page with:
member_action :confirm, :method => :get do
old_estimate = Estimate.find(params[:id])
new_estimate = Order.create(old_estimate.attributes.merge({:id => nil, :created_at =>
nil,:updated_at => nil}))
old_estimate.line_items.each do |li|
new_estimate.line_items.create(li.attributes.merge({:id => nil, :created_at => nil,
:updated_at => nil}))
end
redirect_to edit_customer_order_path(new_estimate.customer, new_estimate)
end
but I would like to use the "new" action and create the record only after it has been edited and confirmed.
I tried to use
redirect_to new_customer_order_path(old_estimate.customer, old_estimate.attributes)
and it will render the new form but without any parameters in it.
The params are in the URL but I got an "Unpermitted parameters:" in the log. All the params are permitted under Active Admin(either under other.rb and estimate.rb) as:
permit_params :id, :customer_id, :title, :edd, :total,
line_items_attributes: [:id, :cartable_id, :cartable_type, :product_type, :source_lang, :dest_lang, :unit_price, :total, :_destroy]
Anyone have any suggestion?
You can override the new action to set some default value in the form:
controller do
def new
record = YourActiveRecordModel.new #or find, if you pass id
record.some_attribute = some_value
new!
end
end
The corresponding input will be filled.

ActiveRecord::AssociationTypeMismatch: User expected, got Fixnum

I don't understand why I get the following error:
ActiveRecord::AssociationTypeMismatch: User(#29943560) expected, got Fixnum
when I do that in rails console: #game = Game.create(:player => 1060, :played => 1061)
I just want to create a new Game regarding model associations below.
class User < ActiveRecord::Base
has_many :game_as_player, :class_name => 'Game', :foreign_key => 'player_id'
has_many :game_as_played, :class_name => 'Game', :foreign_key => 'played_id'
end
class Game < ActiveRecord::Base
belongs_to :player, :class_name => 'User'
belongs_to :played, :class_name => 'User'
attr_accessible :player, :played, :score, :details, :viewed, :read
end
If anyone has an idea...
Thanks a lot!
It just says that it want a User and you give a Fixnum
You should do something like
#game = Game.create(:player => Player.find(1060), :played => Player.find(1061))
Or, if you want to give the users by ids
#game = Game.create(:player_id => 1060, :played_id => 1061)

Why is my many-to-many-through association failing?

I have set up a twitter-like following model. Users can all subscribe to each other. I am getting an error in my users controller when trying to create the relationship.
user.rb:
has_many :subscriptions
has_many :providers, :through => :subscriptions
has_many :followings, :class_name => "Subscription"
has_many :followers, :through => :followings
subscription.rb
belongs_to :provider, :class_name => 'User', :foreign_key => "provider_id"
belongs_to :follower, :class_name => 'User', :foreign_key => "follower_id"
users_controller.rb
69 def follow
70 logger.debug params.to_yaml
71 #user = User.find(params["user_id"])
72 logger.debug #user.to_yaml
73 if current_user.providers << #user
74 flash[:notice] = "Subscribed"
75 else
76 flash[:error] = "Unable to subscribe."
77 end
78 end
This is the error when I call follow:
ActiveRecord::UnknownAttributeError (unknown attribute: user_id):
app/controllers/users_controller.rb:73:in `follow'
I have verified that I ran rake db:migrate - the subscription table has two fields provider_id and follower_id. Can anyone help me with the error and explain why it is looking for a 'user_id' attribute?
Update:
show.html.erb:
<%= button_to "Subscribe", user_follow_path(#user), :remote => true %>
routes.rb:
resources :users do
resources :locations
resources :saved_events
resources :saved_locations
post "follow"
end
rake routes | grep follow:
user_follow POST /users/:user_id/follow(.:format) {:action=>"follow", :controller=>"users"}
Using Michael Hartl's tutorial as a guide, I came up with this solution, which fixes the data model so that collection functions work as they should.
Make the provider id accessible and remove the foreign keys in the subscription model.
subscription.rb:
attr_accessible :provider_id
belongs_to :provider, :class_name => 'User'
belongs_to :follower, :class_name => 'User'
Add foreign keys for subscriptions and reverse_subscriptions in the user model.
user.rb:
has_many :subscriptions, :foreign_key => "subscriber_id", :dependent => :destroy
has_many :subscribed_to, :through => :subscriptions, :source => :provider
has_many :reverse_subscriptions, :class_name => "Subscription", :foreign_key => "provider_id", :dependent => :destroy
has_many :followers, :through => :reverse_subscriptions
I also added helper methods to the user model.
user.rb:
def following?(provider)
subscriptions.find_by_provider_id(provider)
end
def follow!(provider)
subscriptions.create!(:provider_id => provider.id)
end
def unfollow!(provider)
subscriptions.find_by_provider_id(provider).destroy
end
Then, in the controller, we can call follow! or unfollow!
user_controller.rb:
...
current_user.unfollow!(#user)
...
current_user.follow!(#user)
...
The reason it's giving you a error is because the when you call << on the providers collection the user doesn't know it's supposed to be a follower. So it's basically saying, "I'm a user, add me to this collection of providers!" instead of "This guy is going to follow me, I'm now a provider and he's a follower"
The simplest answer may be to just do
user.rb:
def follow(other_user)
Subscription.create(:provider => other_user, :follower => self)
end
users_controller.rb
def follow
#user = User.find(params["user_id"])
if current_user.follow(#user)
flash[:notice] = "Subscribed"
else
flash[:error] = "Unable to subscribe."
end
end

Nested Forms not passing belongs_to :id

I have the following model
class Project < ActiveRecord::Base
has_many :assignments, :conditions => {:deleted_at => nil}
has_many :members, :conditions => {:deleted_at => nil}
accepts_nested_attributes_for :members, :allow_destroy => true
end
class Member < ActiveRecord::Base
belongs_to :project
belongs_to :person
belongs_to :role
has_many :assignments, :dependent => :destroy, :conditions => {:deleted_at => nil}
accepts_nested_attributes_for :assignments, :allow_destroy => true
validates_presence_of :role_id
validates_presence_of :project_id
end
and I assume the controller will populate the member.project_id upon project.save for each nested member record. However, I get a validation error stating the project_id is blank.
My controller method:
def create
# #project is created in before_filter
if #project.save
flash[:notice] = "Successfully created project."
redirect_to #project
else
render :action => 'new'
end
end
Do I need to manually set the project_id in each nested member record? Or what is necessary for the controller to populate when it creates the member records?
Create the Member object like this:
#member = #project.members.build

Resources