RoR 4 - Update model with related model - ruby-on-rails

How I can add a model with a model related:
#user = User.find( cookies[:id] )
#u = #user.advert
#advert = #u.create(advert_params)
This model is saved correctly, but when I try to add a model related, but the property town is not updated
#user = User.find( cookies[:id] )
#u = #user.advert
#u.advert.town = Town.find(1)
#advert = #u.create(advert_params)
The relation between advert and town is (1 town has many adverts)
What am I doing wrong?

#u.advert.town = Town.find(1)
But if, as you state:
#u=#user.advert
Then, the first line of this answer translates into
#user.advert.advert.town = Town.find(1)
You should probably do:
#u.town = Town.find(1)

Related

How to use .where NULL in Ruby on Rails

I have items in a table that have :parent_id that are empty to signify it being a main category. I was wondering how to iterate over these using .where (if that's even the right method to call).
Here's my controller:
def new
#title = 'New Post';
#post = Post.new
#categories = BlogCategory.all
#cat_zero = BlogCategory.where(:parent_id NULL)
#cat_one = BlogCategory.where(parent_id: 1)
#cat_two = BlogCategory.where(parent_id: 2)
#cat_three = BlogCategory.where(parent_id: 3)
#cat_four = BlogCategory.where(parent_id: 4)
end
The rest works fine, it's just that NULL isn't working. (The relationship between BlogCategory and Post have been made.)
I have tried doing these, but with no fortune (and a few other versions of these):
#cat_zero = BlogCategory.where(:parent_id == NULL)
#cat_zero = BlogCategory.where(:parent_id.nil?)
Thanks for the help!
The spelling you're looking for is:
#cat_zero = BlogCategory.where(parent_id: nil)
It's just the same as the spelling for other values, only using nil.

how to merge collections in rails?

I am a newbie at rails and i wanted help on how to merge collections of two active record objects?
An article has many comments
class Article < Content
has_many :comments
I want to create a new article with comments merged from the comments of source and target article objects.Below, source_id and target_id are ids of two Articles. I want to get comments from them and merge them and add to the new article.
source_id = params[:id]
target_id = params[:merge_with]
#article = Article.get_or_build_article()
#article.allow_comments = true
article_source = Article.find(source_id)
article_target = Article.find(target_id)
#reassign all comments of first article
first_comments = article_source.comments
first_comments.each do |c|
c.article_id = #article.id
c.save
end
#reassign all comments of second article
second_comments = article_target.comments
second_comments.each do |d|
d.article_id = #article.id
d.save
end
#article.title = article_source.title
#article.body = article_source.body + " " + article_target.body
#article.author = article_source.author
#article.save
I see that the new article is created but it doesnt display any comments. So, the linking is broken somewhere. I appreciate any help! Thanks!
You have not saved #article in database. So #article.id is nil.
first_comments.each do |c|
c.article_id = #article.id
c.save
end
So this loop, assigns nil to c.article_id. So first save the #article then update comments. Also use update_all for updating comments instead of looping.
source_id = params[:id]
target_id = params[:merge_with]
#article = Article.get_or_build_article()
#article.allow_comments = true
article_source = Article.find(source_id)
article_target = Article.find(target_id)
#article.title = article_source.title
#article.body = article_source.body + " " + article_target.body
#article.author = article_source.author
#article.save
#reassign all comments of first article
first_comments = article_source.comments
first_comments.update_all(article_id: #article.id)
#reassign all comments of second article
second_comments = article_target.comments
second_comments.update_all(article_id: #article.id)
Or even better to update comments use this
Comment.where(article_id: [article_source.id, article_target.id]).update_all(article_id: #article.id)

How can I iterate through a model then iterate again in my view?

I want to pull data for each of my users. I grab their person_id from my user table, then use each person's ID to figure out how many days each person has available, and show that in my view.
I'm not sure if I am doing this correctly because I am iterating in my controller then again in my view.
def how_many_days_users_have
#my_group = User.all.pluck(:person_id)
#my_group.each do |v|
#indirect_id_v = Empaccrl.where("person_id = ? and is_active = ?", '#{v]', 'Y').pluck(:a_code).first
#v_range = Empaccrl.where("person_id = ? and is_active = ?", '#{v]', 'Y').pluck(:ac).first
#v_range_taken = Empaccrl.where("person_id = ? and is_active = ?", '#{v]', 'Y').pluck(:taken).first
#total_v_hours = #v_range.to_d - #v_range_taken.to_d
#total_v_days = #total_v_hours / 8
end
Then in my view I use this to show me this data:
%tr.trace-table
-#indirect_id_v.each do |idd|
%tr.trace-table
%td.trace-table{:style => 'border: solid black;'}= idd
-#total_v_days.each do |days|
%tr.trace-table
%td.trace-table{:style => 'border: solid black;'}= days
Okay, first things first, move some of that junk to your model, like so:
class Empaccrl < ActiveRecord::Base
def self.all_people
where(person_id: User.all.pluck(:person_id))
end
def self.active_people
all_people.where(is_active: 'Y')
end
def self.active_vacation_data
active_people.select(:person_id, :ac, :taken)
end
def total_v_hours
ac.to_d - taken.to_d
end
def total_v_days
total_v_hours / 8
end
end
Then you can use:
peoples_vacation_information = Empaccrl.active_vacation_data.all
peoples_vacation_information.map do |person|
p "person #{person.person_id} has #{person.total_v_days} vacation days"
end
Honestly, you don't even need all that, but I'm not sure why you are doing what you are doing, so I figured better be safe and add stuff. Whatever you don't need, just ignore.

POST Multiple Row to Database with fill out only one form on RAILS

I'm try to develop one rails application.
When I fill out the form, I'm getting this parameter.
"daysoff"=>{"offdate"=>"06/08/2015, 06/09/2015, 06/10/2015, 06/11/2015, 06/12/2015", "assign_id"=>"3", "user_id"=>"2"}
Here is my index controller,
def index
#people = User.all
#user = User.current
#daysoff = Daysoff.new
end
My table coloumns are offdate (date), user_id (int), :assign_id (int), so i want to post each date for one row and other column values must be same.
How should i write create controller ?
You could do something like
off_dates = params["daysoff"]["offdate"].try(:split,',')
off_dates.each do |off_date|
days_off = Daysoff.new
days_off.offdate = Date.strptime(off_date.strip, "%m/%d/%Y")
days_off.user_id = params["user_id"]
days_off.assign_id = params["assign_id"]
days_off.save!
end

does a after_created Rails callback method on a model have an instance of the newly created model?

I have a after_create method for my Contact model.
However, when I put the value, it comes out nil. How can I have a callback for a newly created model ( I do a fair amount of transformation in the create model) referenced within the callback method?
after_save :update_company
def update_company
puts self.inspect
puts self.company
if company.phone.empty?
company.phone = self.phone
company.save
end
end
When I look at the logs for self.inspect, it doesn't show any of the transformations used in the create method...yet, this should run only after it has created (and saved), the object, right?
Here is the create method:
def create
#contact = Contact.create(params[:contact])
unless #contact.vcard.path.blank?
paperclip_vcard = File.new(#contact.vcard.path)
#vcard = Vpim::Vcard.decode(paperclip_vcard).first
#contact.title = #vcard.title
#contact.email = #vcard.email
#contact.first_name = #vcard.name.given
#contact.last_name = #vcard.name.family
#contact.phone = #vcard.telephone
#contact.address.street1 = #vcard.address.street
#contact.address.city = #vcard.address.locality
#contact.address.state = #vcard.address.region
#contact.address.zip = #vcard.address.postalcode
#contact.company_name = #vcard.org.fetch(0)
end
#contact.user_id = current_user.id # makes sure every new user is assigned an ID
if #contact.save
flash[:notice] = "Successfully created contact."
redirect_to #contact
else
render :action => 'new'
end
end
Yes, this happens because you didn't use self when assigning the value to company object.
In ruby, generally you don't require the use have "self" to retrieve attributes of an instance
for example in your code. you can puts company and it would work fine.
but when assigning (on the left hand side ) you always have to use self.
so change this in your code.
self.company.phone = self.phone
company.save
or
self.company.phone = phone
company.save

Resources