Updating several records for same object - ruby-on-rails

Ok I'm really feeling I'm missing the rails way on this one.
Following my last question rails parameters in form_for, I can correctly update the message contents but am struggling with updating the recipients
My Draft model
class Draft < ActiveRecord::Base
belongs_to :message
belongs_to :draft_recipient, :class_name => "User"
delegate :created_at, :subject, :user, :body, :draft_recipients, :to => :message
...
My Message Model
class Message < ActiveRecord::Base
belongs_to :user
has_many :recipients, :through => :message_copies
has_many :draft_recipients, :through => :drafts
has_many :message_copies
has_many :drafts, :class_name => "Draft", :foreign_key => :message_id
attr_accessor :to #array of people to send to
attr_accessible :subject, :body, :to, :recipients, :author, :user
...
In my controller I want to do something like
new_draft_recipients = params[:draft][:draft_recipients].split(",")
#draft.update_attributes(:draft_recipients => new_draft_recipients)
which obviously doesn't work. When I try update each record comparing old (from the database )and new recipients (passed through the form), the algorithm gets ridiculously complicated. I feel what is missing is proper associations, but I don't manage to understand which. I know this is really simple. Thanks for your help

Related

Rails - how to make association between these models (not based on "id", but on "email")

I have these models that obviously have more attributes, but for simplicity I kept them just like this:
class User < ActiveRecord::Base
has_many :subs, :foreign_key => :email, :class_name => "subs"
end
class Subscription < ActiveRecord::Base
belongs_to :plan
belongs_to :user
end
In the table subscriptions, there's a column called email. This column points to the table users where matches an email address of a single user (the column email is in both tables unique).
I would need to create an association between these two models based on the email value. But when I try to run this query (and to get all subscription for the currently sign in user):
<%= current_user.subs.inspect %>
I get this error message:
uninitialized constant User::subs
I'd like to ask you guys for helping me with this association.
Thanks
uninitialized constant User::subs
This code
class User < ActiveRecord::Base
has_many :subs, :foreign_key => :email, :class_name => "subs"
end
should be like this
class User < ActiveRecord::Base
has_many :subs, :foreign_key => :email, :class_name => "Subscription"
end
When you are using a class_name option with the associations,it should point to the respected model classname(in your case it is Subscription not subs).Since there is no model with the classname subs,it throws that exception.
class User < ActiveRecord::Base
has_many :subs, :foreign_key => :email, :class_name => "Subscription", :primary_key => :email
end
class Subscription < ActiveRecord::Base
belongs_to :plan
belongs_to :user, :foreign_key => :email, :class_name => "Subscription", :primary_key => :email
end
You have to set the correct Class name and also you have to set the primary key.

Rails: ActiveRecord association won't work when specifying foreign key

I am trying to set up an ActiveRecord association. Below are my two classes and I'm specifying the foreign_key option that I've read about here: api.rubyonrails.foreignkey
School
class School < ActiveRecord::Base
has_many :students, :foreign_key => :institutionid
attr_accessible :name, :city, :state, :zipcode, :institutionid
end
Student
class Student < ActiveRecord::Base
belongs_to :school, :foreign_key => :institutionid
attr_accessible :firstname, :lastname, :institutionid
end
Database Schema
dbo.school {id:int, institutionid:int, name:nvarchar(255), city:nvarchar(255), state:nvarchar(2), zipcode:nvarchar(25),}
dbo.student {id:int, institutionid:int, firstname:nvarchar(255), lastname:nvarchar(255)}
When trying to access the above with <% debug #school.students %> I get the following output on the page --- []
Can anyone help me find out what I'm doing wrong? Or provide some other ways of troubleshooting the issue? Thanks!
I think you are asking for all of the students that have an institutionid of 433. However institutionid is not the primary key of School (and I wonder why not?). So when you say school.students, the query will use the value in 'id' not in 'institutionid'. I would try changing Student's association to:
belongs_to :school, :foreign_key => :institutionid, :primary_key => :institutionid
and change School to:
has_many :students, :foreign_key => :institutionid, :primary_key => :institutionid

has_many through with :class_name

I have the following:
belongs_to :type, :class_name => :activity_type
belongs_to :activity_type # needed for has_one :through?
has_one :category, :through => :activity_type, :class_name => :activity_category
Is there a way to do this "has_one through" relationship using "type" instead of "activity_type"?
Edit: This was not working, and I failed to see thanks to the magic word "type".
What I have now is this:
belongs_to :company
belongs_to :type, :class_name => 'ActivityType', :foreign_key => 'activity_type_id'
has_one :category, :through => :type, :class_name => 'ActivityCategory', :foreign_key => 'activity_category_id'
But it fails with
no such column: activity_types.category_id
which is correct, since the expected column would be "activity_types.activity_category_id". How can I fix that?
You're using associations in a wrong way. First of all when you use through: then class_name, foreign_key will be omitted. So this is why it's expecting category_id. Also I think that you shouldn't overload your associations with rewriting defaults options since when there's a lot of associations on a model it starts to look like a mess and hard to understand. So you probably should just write it as belongs_to :activity_type and add whatever name suits you best like alias_method :type, :activity_type.
So in short, this is what I'm proposing you:
belongs_to :company
belongs_to :activity_type
has_one :activity_category, :through => :activity_type
alias_method :type, :activity_type
alias_method :category, :activity_category

Validation on associtions in rails with roles

So I have two ActiveRecord classes
class User < ActiveRecord::Base
has_many :buyer_deals, :class_name => "Deal", :foreign_key => :buyer_id
has_many :seller_deals, :class_name => "Deal", :foreign_key => :seller_id
validates_presence_of :name # THIS SHOULD ONLY BE RUN IF USER IS A SELLER
# IN THE DEAL
validates_presence_of :phone # THIS SHOULD ONLY BE RUN IF USER IS A BUYER
# IN THE DEAL
end
class Deal < ActiveRecord::Base
belongs_to :seller, :class_name => 'User'
belongs_to :buyer, :class_name => 'User'
validates_associated :seller
validates_associated :buyer
end
What I want to do is create a new deal with.
Deal.create(A NICE STRUCT WITH SELLER AND BUYER)
However I only want to run the name validation if the relation from the deal is a seller and the phone if the the relation from the deal is a seller, is this possible in rails, does not seem to find anything in the documentation.
You should be able to do this by adding a condition to you validation.
So, your User class would wind up looking something like...
class User < ActiveRecord::Base
has_many :buyer_deals, :class_name => "Deal", :foreign_key => :buyer_id
has_many :seller_deals, :class_name => "Deal", :foreign_key => :seller_id
validates_presence_of :name, :if => :has_an_active_seller_deal?
validates_presence_of :phone, :if => :has_an_active_buyer_deal?
def has_active_seller_deals?
seller_deals.count > 0
end
def has_active_buyer_deals?
buyer_deals.count > 0
end
end
An alternative to this would be to simply require all users to have a name and phone number on file at all times (no conditional validation), and only reveal it to other users with which they had active deals, and not as part of a user's public profile, thereby protecting the user's privacy when possible. This would probably be simpler.
You could put the validations in a callback:
before_save :check_user_type
private
def check_user_type
user_type = self.responds_to?(seller_id) ? :seller : :buyer
if user_type == :seller
validates_presence_of :name
else
validates_presence_of :phone
end

Rails Associations Not working and not recognizing classes

I have a weird bug that just popped up with my rails app that I cannot figure out. I recently added a new association to an existing Model and now my previous associations do not want to work properly.
#=> self.user
#=> <# user.id => "1" ...
#=> self.transactions
#=> [<# transaction_id => "1"...
#=> self.credit_plan
#=> nil
So the first two associations work fine via, but for some reason credit_plan returns nil and is crashing all my existing working code. Here is the record associations I have.
class Order < ActiveRecord::Base
belongs_to :user
belongs_to :credit_plan
has_many :transactions, :class_name => "OrderTransaction"
.
class CreditPlan < ActiveRecord::Base
scope :active, where({:is_active => true})
scope :inactive, where({:is_active => false})
has_many :orders, :class_name => "Order"
.
class OrderTransaction < ActiveRecord::Base
belongs_to :order
serialize :params
Alright Guys, I figured it out. If I had posted more context of my files, I'm sure someone would have figured it out and helped me sooner.
So basically, when I was setting up my virtual attributes for the credit card form, I accidentally stomped on my own name space by adding :credit_plan as an attribute, which overrides the association.
class Order < ActiveRecord::Base
belongs_to :user
belongs_to :credit_plan
has_many :transactions, :class_name => "OrderTransaction"
validates_presence_of :credit_plan_id, :user
attr_accessor :first_name, :last_name, :card_type, :credit_card,
:number, :verification_value, :promotional_code, :expires_on,
:credit_plan # << This will override associations, delete to fix.
validate :validate_card, :on => :create

Resources