Rails custom Coupon-System - ruby-on-rails-4

I creating a simple e-commerce for a friend and i want to implement a coupon system. I want coupons to be a new model and admin to be able to create a new coupon from admin panel like a simple scaffold.
My models are this for now.
class Order < ActiveRecord::Base
has_many :order_items
class OrderItem < ActiveRecord::Base
belongs_to :product
belongs_to :order
I know that i need an association Orders -> Belongs_to :coupon and Coupons -> has_many :orders or Orders -> has_one :coupon and Coupons -> belongs_to :orders. I want any order to have only one coupon.
But my main problem is how to create a form , to check if a coupon exists.
I know how to update the total_price etc.
Thank you.

Simply make sure that the name or some other attribute of the coupon is unique in the Coupon.rb model. See the link below for more information.
http://guides.rubyonrails.org/active_record_validations.html#uniqueness
Then you can index the Coupons by Coupon.name. This is will help two ways 1) if your admin attempts to create a coupon with a duplicate name or code they will get an error saying that coupon exits. 2) When a consumer enters a coupon you can simply check if it exits by calling Coupon.find_by_name('NAME') where NAME is what the consumer entered. If that returns nil then clearly they entered a coupon that was not created.

Related

How do I create a foreign key in rails 5 if I've already created the models for the tables I want to associate?

All of the references I've found either show me how to do it upon table creation, or are for a much earlier version of rails. Ideally, I'd like like the foreign_key to be named 'author_id' in the questions table to distinguish it from other users who may be leaving comments or answers later.
class Question < ApplicationRecord
belongs_to :user
end
class User < ApplicationRecord
has_many :questions
end
You can create a new empty migration file in your terminal via rails generate migration RenameUserFkOnQuestion. Open it up and build your migration. This is a handy guide if you're not sure on the name of something.
def change
change_table :questions do |t|
t.rename :user_id, :author_id
end
end
Run the migration and head over to your models. You'll need to update your relationships like so:
class Question
belongs_to :author, class_name: 'User'
end
class User
has_many :questions, inverse_of: :author
end
Then you should be good to go.

How to add foreign_key pointing to same table?

I've got a table 'users' but one user might be a manager of another user, one user could also be a manager of many other users, so its a one-to-many relationship, and it only involes one table. heres my approach:
1.I've added 'manager_id'(which really stores another uners id) column to users table.
2.I've defined relationship in User model class:
belongs_to :manager, foreign_key: 'manager_id',class_name:'User'
has_many :minions, class_name:'User'
Now, say in rails console if i set one users 'manager_id' to another users id its all fine. but if i try to use methods like 'user.manager' or 'user.minions' it says those methods aren't defined. Were have i gone wrong?
I think you want to implement self inheritance that can be done as :
class User < ActiveRecord::Base
self.inheritance_column = :child_class
has_many :minions, :foreign_key => :parent_id, :as => :parent
belongs_to :parent, :polymorphic => true
end
This is just a sketch of what i understood from the above description, it can be enhanced.

Overriding a child association's setter from the parent model

I have a parent User model, and each user has_one Contact which hold's the user's contact info.
One of the contact fields is the email. For various legacy reasons and reasons outside the context of this question, I'd love to be able to call #email directly as if it were a property of User
In other words I'd like to do this -
user.email
user.email = "foo#example.com"
Instead of this -
user.contact.email
user.contact.email = "foo#example.com"
I laid out my models as follows, overriding the child's getter/setter from the parent User -
class User < ActiveRecord::Base
has_one :contact
def email
contact.email
end
def email=(value)
contact.email = value
end
end
class Contact < ActiveRecord::Base
belongs_to :user
end
You may have already noticed the problem with the setter - when the User is saved, it doesn't save the child model.
What's the most robust to work around this?
Thanks!
Ok, found the solution for anyone curious - auto-saving
ActiveRecord::AutosaveAssociation is a module that helps with exactly this - saving child associations properly when the parent is saved.
Just need to include an autosave: true. Example -
has_one :contact, autosave: true
It also takes care of destroying records marked for deletion, and a few other fancy things.
I also did a quick check, and it smartly doesn't hit the DB unless it really needs to. That is, if you update the parent only it doesn't bother saving the child association with an other SQL UPDATE statement.
Check out the documentation here.

How to associate these models(user, company), where User can be Employer and Employee?

In Ruby on Rails 4, I've these models:
def User < ActiveRecord::Base
has_one :company, dependent: :destroy
end
def Company < ActiveRecord::Base
belongs_to :user
end
So now, I want User as Employer to be able to have a company, and this Company can have many Users(Employees).
And when I log a User as Employee, I want to able to list all the companies he works.
What is the best way to do this?
I'm not sure I could give you a full working code file without some more information, but I think this is the best way to proceed.
class User < ActiveRecord::Base
self.table_name = "users"
#Define shared associations/methods
end
class Employee < User
has_and_belongs_to_many :companies
#Employee only associations/methods
end
class Employer < User
has_one :company
#Employer only associations/methods
end
class Company < ActiveRecord::Base
has_and_belongs_to_many :employees
belongs_to :employer
end
Since both inherit from the same User model, they will share a table. Since both derived models only use has_x, the foreign key will be in the other table, meaning they can share a table schema without a ton of null values.
Again I'm not sure this will work by itself, but I think it's a good start. Another advantage is that by segregating the code like this, you can independently change functions by the type of person (e.g. you could have a generic log function on user, but make it more specific on Employee and Employer - such as including the company or companies they are tied to).
I realized after the fact that there is another way of doing this. You can make User have a polymorphic association to either Employee or Employer. Then you would check the user record for which type it is, then pull the association and call the methods on that record (Employee or Employer).
The only thing I don't like about this solution is that it involves 3 tables and from what I've seen you can get by with 1.

Only show one form for nested_attribute

I would like to show only one nested form for the one-to-many relationship between user and appointments. A user can only create one appointment and the form should only show fields for one appointment regardless of how many appointments he has.
I've tried the :limit option
class User
has_many :appointments, dependent: :destroy
accepts_nested_attributes_for :appointments, limit: 1
end
I also tried limiting the number of appointments built in the controller
class UsersController
def edit
#user = current_user
1.times { #appointment = #user.appointments.build }
end
end
I always end up with a nested form for each appointment the user has plus an additional nested form. I know I could change the relationship to one-to-one but this is for legacy code and its likely that the relationship will be one-to-many in the future.
Is there a way that I can only show one nested form regardless of how many appointments a user has?