We are creating a scheduling app and attempting to create a copy/paste function for schedules from week to week. I am trying to figure out how to duplicate a schedule for certain period of time, while updating the attributes upon paste. Right now I can copy the schedule, but when running it on postman, the dates and times stay the exact same (as we would expect with a .dup.) I believe it would be best to set the start/end times to nil and then upon paste maybe the attributes get updated at that time?
Here is the function I have so far:
def copy
set_calendar
if params["start_date"] && params["end_date"]
start_date = params["start_date"].to_date
end_date = params["end_date"].to_date
if #calendar.users.owners.include?(current_user) || #calendar.users.managers.include?(current_user)
#past_shifts = Shift.where(calendar_id: #calendar.id, start_time: start_date.beginning_of_day .. end_date.end_of_day).to_a
if
#past_shifts.each do |past_shift|
shift = past_shift.dup
shift.users = past_shift.users
shift.update(shift_params)
shift.save
end
render json: "copied", status: :ok
else
render json: #usershift.errors, status: :uprocessable_entity
end
else
render json: ("You do not have access to copy shifts"), status: :unauthorized
end
end
end
The shift.update(shift_params) is the part that needs to update the start and end times. Here are the shift params:
def shift_params
params.permit(:start_time, :end_time, :calendar_id, :capacity, :published)
end
As far as relationship set ups, this current method is being created in the shifts controller. Shift has many users through usershifts, user has many shifts through usershifts, and usershift model belongs to both.
Just curious - are you sure params for your copy method contains values for start_time and end_time? If so, why not to use them directly:
shift.start_time = params['start_time']
shift.end_time = params['end_time']
With use shift_params you will also update other 3 attributes: :calendar_id, :capacity, :published. Not sure if this is necessary in this case.
Using shift.update method, in this case, is not reasonable. It works with existing record and saves updated attributes to the database. In your case the record is new, and you save all the changes with calling shift.save later.
Related
I want to change the value of field ( that changes to the date of the day for example)
automatically or when you access an already created view the action is generate in odoo13.
Thaks
You should use fields_view_get method, it will fired with every type of view, if you need it when a form is open you can do something like this:
#api.model
def fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False):
res = super(Movimiento, self).fields_view_get(
view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu
)
if view_type == 'form':
# Get today date
today = fields.Date.context_today(self)
# update your field here.
return res
I hope this answer can be helpful for you.
Hi I have a model called PurchasingGroup, a purchasing group has many Goals.
Goal model has 2 attributes: no_of_users and discount
I need to validate that the goals are consecutive, for example if I create a Goal with no_of_users = 10 and discount = 15 then the next goal I create must have greater values, otherwise I have to show the error to the user, right now Im making the validation in the create action of the controller, I know it is a bad practice so I want to know how to create this validation, I could not achieved it using custom validations in the model level.
I need to access the purchasing group and then check if the last group goal values are greater than or equal to the values of the new goal:
Below is the validation I have in the controller, it works but I want to do it right:
def create
respond_to do |format|
#purchasing_group = PurchasingGroup.find params[:purchasing_group_id]
#goal = Goal.new goal_params
#error_messages = ""
if not #purchasing_group.goals.empty?
if #purchasing_group.goals.last.no_of_users >= #goal.no_of_users
#error_messages = "The goals are consecutive! No. Users: must be greater than the previous goal value"
end
if #purchasing_group.goals.last.discount >= #goal.discount
#error_messages = "#{#error_messages}\nThe goals are consecutive! discount: must be greater than the previous goal value"
end
end
#if there are no errors then we save the object
if #error_messages.empty?
if #goal.save
#goal.update_attributes purchasing_group_id: params[:purchasing_group_id]
end
end
#In a js template I handle the errors, that is not relevant for this question.
format.js
end
end
if I understood you right, then:
validate :count_no_of_users
private
def count_no_of_users
last_goal = PurchasingGroup.find(self.purchasing_group_id).goals.last
error(:count_no_of_user, "Should be more than #{last_goal.no_of_user}") if self.no_of_user < last_goal.no_of_user
end
and same for discount
you can validate it in single or separate validations.
I have a question regarding the execution order in a Rails method : Here what I do in my model :
def update_fields
FillMethods.fill_info("BadgeUser", "Badge", self.id, self.badge_id, "badge_")
self.reload
self.update_attributes(:completed => true) if self.badge_goal == 0
end
I have an object, then I apply the FillMethods info on it to fill some fields in this object and save it. Then I want to check if badge_goal == 0 to mark it as completed.
The issue I have is that if I don't put self.reload the self item will not be updated, the object will be in the database but the self item will be the same as before the FillMethods. If I do self.reload the self item is correct and it can be marked as completed correctly
My question is will ruby wait for the FIllMethods to be done to reload the self or it will reload the self before the FillMethods is done ?
Why does the self item is not correct if I don't do self.reload ?
The FillMethods is a module in my lib directory.
Thanks for your help,
Thats my fill method :
module FillMethods
def self.fill_info(model1, model2, id1, id2, string)
parameters1 = model1.constantize.attr_accessible[:default].to_a.map {|s| s.dup}
parameters1.delete_if {|s| !s.start_with?(string)}
parameters2 = parameters1.map {|s| s = s.split(string)[1]}
h = Hash[parameters1.zip parameters2]
object1 = model1.constantize.find(id1)
object2 = model2.constantize.find(id2)
h.each do |parameter1, parameter2|
object1.update_attribute(parameter1.to_sym , object2.send(parameter2))
end
return object1
end
end
The goal of the method is to fill the BadgeUser table with all the badge info.
For each column in my Badge table (like name) I have in my BadgeUser table badge_name
Thanks,
I cannot be sure without seeing the code, but judging from the parameters you pass, I guess that FillMethods.fill_info retrieves the record from db again, using the third parameter id. It then changes the record and stores it back.
Your object (self) has no way, under ActiveRecord or similar, to know that the db was modified somewhere somehow.
Note that you are retrieving the same record from db some three times instead than once.
If you change FillMethods.fill_info to instead accept a record (self itself), and modify it, then self would be in the new state.
Addendum
Ruby code is executed sequentially in a single thread unless you explicitly start a new thread, so yes, .fill_info is executed before continuing with the rest of update_fields.
I am using rails_admin 0.0.5 and want to add a functionality (if not exist).
I want to copy data from one table to another. I have two database tables, both accessible from rails_admin. How to copy one attribute from one table to another.
eg.
requests_table => emails|request_approve
approval_table => emails|sent_confirmation
and I want to copy emails from approval_table to emails in approval_table.
I didn't understand this, so please do not refer. https://github.com/sferik/rails_admin/wiki/Custom-action
This method will copy all the requests and save them in approval table.
I would add another attribute called, copied to request table. This would indicate those requests that's been copied already and avoid duplicates in approval table.
def copy_table
#requests = Request.find_all_by_copied(false)
#requests.each do |r|
#approval = Approval.new
#approval.email = r.email
#approval.sent_confirmation = r.request_approve
#approval.save
#requests.update_attributes(:copied => false)
end
end
We are trying to optimize our views and on a page where 40 pictures are loaded with the following code :
= image_tag(product.pictures.first.data.url(:gallery))
We have a load time of 840ms, if we change it to the following code :
= image_tag("http://bucketname.s3.amazonaws.com/products/#{product.pictures.first.id}/gallery.jpg?1325844462"
We become a load time of 220ms.
It means the interpolation of s3_path_url is very slow. Somebody else is expecting the same problems? For the moment I created a helper that generates my urls :
def picture_url(picture, style)
"http://bucketname.s3.amazonaws.com/products/#{picture.id}/#{style}.jpg"
end
Only problem I have here is that the cache key is not there and also the extension not.
Is there always just one image of each product shown on the gallery page?
What about a cache column in your database. Whenever you create or update an image you could save this image_url as gallery_picture_url in your database and call it directly like
= image_tag(product.gallery_picture_url)
class Product < ActiveRecord::Base
after_commit: :update_gallery_picture_url
def update_gallery_picture_url
self.update(gallery_picture_url: self.pictures.first.data.url(:gallery)) if self.gallery_picture_present?
end
def gallery_picture_present?
(self.pictures.first.data.url(:gallery) rescue false).present?
end
end