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
Related
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.
i have the following models
class User
has_many :projects, :through => :bids
has_many :bids, :dependent => :destroy
end
class Project
attr_accessible :name, :user_id
has_many :users, :through => :bids
has_many :bids, :dependent => :destroy
belongs_to :projectmanager, :class_name => "User", :foreign_key => "user_id"
end
class Bid
attr_accessible :project_id, user_id
belongs_to :user
belongs_to :project
end
As you can see, my Project class has both *has_many* and *belongs_to* to the same model (User)
In Project controller new I have
def new
#project = Project.new
#project.gencontr = current_user
where current_user is Devise current logged in user.
When I save the project, the column user_id in the Projects table is always null. Can you show me where do I go wrong on this one...Thank you
on create action
def create
#project = Project.new(prams[:project])
#project.projectmanager = current_user
.......
end
I've set up a self-referencial association using has_many :through, basically as described on this Railscast: http://railscasts.com/episodes/163-self-referential-association.
Some "activities" act kinda like "articles" and have an associated set of other activities, hence the naming of the join table. It is a little confusing... I know.
I am having a tough time getting things to save right. Here is what I've got...
activity.rb
class Activity < ActiveRecord::Base
has_many :article_activities
has_many :activities, :through => :article_activities
accepts_nested_attributes_for :activities
end
article_activity.rb
class ArticleActivity < ActiveRecord::Base
attr_accessible :article_id, :activity_id
belongs_to :activity
belongs_to :article, :class_name => "Activity"
end
articles_controller.rb
class ArticlesController < ApplicationController
def new
#activity = Activity.new
#activity.is_article = true
#user_activities = current_user.activities
end
def create
#activity = Activity.new params[:activity]
#activity.is_article = true
#activity.user = current_user
if #activity.save
redirect_to root_path, :notice => "Article created!"
else
render :action => "new"
end
end
new.html.haml
= simple_form_for #activity, :url => articles_path do |f|
/ Other fields omitted for clarity
= f.association :activities, :collection => #user_activities
So, upon submitting the form, #activity in the create action has the expected #activity.activities. However, upon saving #activity and reloading the record, #activity.activities is empty.
Any ideas how to save the associations?
I figured this one out. I had to add a :foreign_key for "article" to the models...
class ArticleActivity < ActiveRecord::Base
attr_accessible :article_id, :activity_id
belongs_to :activity
belongs_to :article, :class_name => "Activity", :foreign_key => "article_id"
end
class Activity < ActiveRecord::Base
belongs_to :user
has_many :article_activities, :foreign_key => "article_id"
has_many :activities, :through => :article_activities
end
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.
class Contact < ActiveRecord::Base
has_many :contact_company_profiles, :dependent => :destroy
accepts_nested_attributes_for :contact_company_profiles, :allow_destroy => true
has_many :companies, :through => :contact_company_profiles
has_many :phones, :as => :phoneable, :dependent => :destroy
accepts_nested_attributes_for :phones
end
class ContactCompanyProfile < ActiveRecord::Base
belongs_to :contact
belongs_to :company
end
class Company < ActiveRecord::Base
has_many :contact_company_profiles
has_many :contacts, :through => :contact_company_profiles
has_many :phones, :as => :phoneable, :dependent => :destroy
end
For above specified models i want respond with JSON format through contact controller the code was working fine until i was accessing till companies the below specified command.
#contacts = Contact.find(:id)
respond_to do |format|
format.html
format.js
format.json { render :json=>#contacts.to_json(:include=>[:companies, :phones) }
format.xml { render :xml => #contacts }
end
But now i want json of nested Phone element of company in my contact controller. So kinldy help me in this regard.
Thanks
When I work on this kind of problem, I often end up overriding serializable_hash
It's the method that's used when generating json and xml. You just build up the hash to contain whatever you want. I often add what I want then pass it to the original. Plus, this way you never have to think about it in the controller. You can always just return it, and the object will do the right thing.
def serializable_hash(options = {})
# TODO exclude the id
options = {:include => [:address],
:except => [:created_at, :updated_at, :creating_user_id]}.merge(options ||= {})
super options
end