I am trying something very simple. At this point I have three models:
Player >> PlayerMatch >> Match
class Match < ActiveRecord::Base
attr_accessible :date, :goals_team_a, :goals_team_b
has_many :PlayerMatches
has_many :Players, :through => :PlayerMatches
end
class Player < ActiveRecord::Base
attr_accessible :name, :password_confirmation, :password, :user
has_many :PlayerMatches
has_many :matches, :through => :PlayerMatches
end
class PlayerMatch < ActiveRecord::Base
attr_accessible :match_id, :player_id, :team
belongs_to :player
belongs_to :match
end
The model PlayerMatch is the join entity. In each Match a player plays, he can be on team A or team B, that is why I made that attribute team on PlayerMatch.
How can I set that value team for each match? I want to do something like:
p = Player.new
//set players attributes
m = Match.new
//set match attributes
p.matches << m
Now I just want to set his team on that specific match.
Thanks in advance!
Using the models you have set up, you can do something like this:
p = Player.create
m = Match.create
pm = PlayerMatch.create(:player => p, :match => m, :team => 'Team')
If you want the PlayerMatch automatically created as in your example, you can retrieve it afterwards and set the team at that point:
p = Player.create
m = Match.create
p.matches << m
pm = p.matches.where(:match_id => m.id).first
pm.update_attributes(:team => 'Team')
Unless you are saying an individual player can play different matches for different teams though, it seems like you may want a Player to belong_to a Team instead.
This post also has some info related to this question.
Related
My models
class Collection < ActiveRecord::Base
has_many :outfits
has_many :products, through: :outfits
end
class Outfit < ActiveRecord::Base
belongs_to :product
belongs_to :collection
end
class Product < ActiveRecord::Base
has_many :outfits
has_many :collections, through: :outfits
end
I want to save product in collection model
so one collection can have few product in it
How can i do it? i'm a bit struggle with it
it have tried something like this
p = Product.find_by_code('0339').id
p.collections.create(product_id:p1)
but i guess i'm wrong
When you're chaining through a through collection you don't need to reference the parent's id since that is known.
Instead of:
p = Product.find_by_code('0339').id # NOTE that you have an 'id' not an object here
p.collections.create(product_id:p1) # you can't call an association on the id
Build the association between two existing models (I'm assuming you have other fields in your models; I'm using name as an example).
p = Product.find_by(code: '0339')
c = Collection.find_by(name: 'Spring 2016 Clothing')
o = Outfit.new(name: 'Spring 2016 Outfit', product: p, collection: c)
o.save!
Assuming p and c exist and assuming o passes validation then you now have an assocaition between one product and one collection using a new outfit as the join table.
p.reload
p.collections.count # => 1
c.reload
c.products.count # => 1
I have a model:
class Delivery < ActiveRecord::Base
has_and_belongs_to_many :dropoff_points, :join_table => :delivery_dropoff_points
end
This model has a field scheduled_date.
This is a DeliveryDropoffPoint class:
class DeliveryDropoffPoint < ActiveRecord::Base
belongs_to :delivery
belongs_to :dropoff_point
end
I need to make sure that when I create a record in rails-admin on any given day the dropoff point gets one and only one delivery.
I tried to implement before_save filter:
class DeliveryDropoffPoint < ActiveRecord::Base
belongs_to :delivery
belongs_to :dropoff_point
def set_scheduled_date
self.scheduled_date = delivery.scheduled_date
end
before_save :set_scheduled_date
validates_uniqueness_of :branch_floor, :scope => :scheduled_date, :message => "floor can only have one job assigned on a given day"
end
However, rails-admin seemed to ignore it, regretfully. Is there any other way to set the value of a column in a join table when selecting the items in the select-box in rails-admin?
Thanks!
I don't seem to get this right for some reason, though it sounds simple :/
I have three models :
User(id,name,email)
Skill(id,name,description)
UserSkill(user_id,skill_id,level)
How can i get all skills of a certain user, whether he or she has discovered them or not ?
For example, 3 skills (walk, talk, write). 3 users (John, Mary, Jack).
If Mary walks and writes, how can i get it back as a result like :
Mary => {Skill: walk(includes UserSkill), Skill : talk, Skill : write(includes UserSkill) }
You get the idea :)
Try this:
class User
def skill_list
Skill.all(
:select =>"skills.*, A.user_id AS user_id",
:joins => "LEFT OUTER JOIN user_skills A
ON A.skill_id = skills.id
AND A.user_id = #{id}").map do |skill|
skill.name + (skill.user_id.nil? ? "" : "(*)")
end
end
end
Now
user = User.find_by_name("Mary")
user.skill_list
Will print:
[
walk(*),
talk,
write(*)
]
I'm assuming you want to set something up like this:
class User < ActiveRecord::Base
has_many :user_skills
has_many :skills, :through => :user_skills
end
class Skill < ActiveRecord::Base
has_many :user_skills
has_many :users, :through => :user_skills
end
class UserSkill < ActiveRecord::Base
belongs_to :user
belongs_to :skill
end
then you can do:
my_user.skills # returns all Skill records assigned to the user
my_user.user_skills.includes(:skill) # this allows you to access :level in addition to Skill attributes
So the way to get both skills and user_skills is to use the :user_skills association. Basic has_many :through. Am I missing something?
user = User.first
user.user_skills.all.map(&:skills)
I have the following:
class Invite < ActiveRecord::Base
belongs_to :user
has_many :invite_recipients
has_many :recipients, :through => :invite_recipients
end
class InviteRecipient < ActiveRecord::Base
belongs_to :invite
belongs_to :user_comm
validates_associated :user_comm, :invite
validates_uniqueness_of :user_comm_id, :scope => :invite_id
end
class UserComm < ActiveRecord::Base
end
I'd like to create a method for Invite with invite_text and a list of UserComms as the variables and then have it create a new invite with the following validations:
1. All UserComms are unique
2. The invite isn't saved unless all the associated InviteRecipients are saved as well
(in other words, the invite isn't valid unless all the created InviteRecipients are valid)
I'm not familiar with how to create model functions. Moreover, when I try something like this:
i = Invite.new(:invite_text => 'come join')
ir1 = InviteRecipient.new(:invite => i, :user_comm => user_comm1)
ir2 = InviteRecipient.new(:invite => i, :user_comm => user_comm2)
i.invite_recipients = [uc1, uc2]
i.save!
I get: SystemStackError: stack level too deep
You need use i.recipients not invite_recipients!
Like this:
i.recipients.create(:user_comm => user_comm1)
i.recipients.create(:user_comm => user_comm2)
In rails, when saving an active_record object, its associated objects will be saved as well. But has_one and has_many association have different order in saving objects.
I have three simplified models:
class Team < ActiveRecord::Base
has_many :players
has_one :coach
end
class Player < ActiveRecord::Base
belongs_to :team
validates_presence_of :team_id
end
class Coach < ActiveRecord::Base
belongs_to :team
validates_presence_of :team_id
end
I expected that when team.save is called, team should be saved before its associated coach and players.
I use the following code to test these models:
t = Team.new
team.coach = Coach.new
team.save!
team.save! returns true.
But in another test:
t = Team.new
team.players << Player.new
team.save!
team.save! gives the following error:
> ActiveRecord::RecordInvalid:
> Validation failed: Players is invalid
I figured out that team.save! saves objects in the following order: 1) players, 2) team, and 3) coach. This is why I got the error: When a player is saved, team doesn't yet have a id, so validates_presence_of :team_id fails in player.
Can someone explain to me why objects are saved in this order? This seems not logical to me.
You should used "validates_associated" to accomplish that
check Here
Something like following no check though
class Team < ActiveRecord::Base
has_many :players
has_one :coach
validates_associated :players, :coach ###MOST IMPORTANT LINE
end
class Player < ActiveRecord::Base
belongs_to :team
validates_presence_of :team_id
end
class Coach < ActiveRecord::Base
belongs_to :team
validates_presence_of :team_id
end
In your controller
t = Team.new
#coach = t.build_coach(:column1=> "value1", :column2=> "value2" ) # This create new object with #coach.team_id= t.id
#players = t.players.build
t.save#This will be true it passes the validation for all i.e. Team, COach & Player also save all at once otherwise none of them will get saved.
Let's look at your failing test:
t = Team.new
team.players << Player.new
team.save!
Adding a new player to the team.players association tries to set the team_id on players right there on line 2. That's just how the << operator works. It doesn't get updated when you save team, so even if team is saved first, player still has a null team_id. In this case you can easily solve it by swapping lines 2 and 3.