Rails 4 Has_One Model Associations/ Retrieving from DB - ruby-on-rails-4

I'm completely stuck. I've read this http://guides.rubyonrails.org/association_basics.html#the-has-one-association and http://guides.rubyonrails.org/active_record_querying.html and am no closer to solving the problem.
I have a belongs_to, has_one model association. In my case it's a User has_one Booth and a Booth belongs_to a User. What I'm trying to do should be simple, create a link so that users who have created a booth can view the booth they created.
To accomplish this, I'm trying to create a 'user_booth' method. I've tried now about 100 different variations, but something like this should work from everything I've read:
def user_booth
#booth = current_user.booth.find_by(id: params[:id])
end
Well, of course that didn't work. I've also tried many variations similar to this:
def user_booth
Booth.find_by(id: params[:id])
end
When I check my database, everything saves exactly as I intended it to, I just can't seem to call on the correct booth that is associated with correct user. Can anyone lead me in a new direction? I'm entirely stuck.
Here is the show method in the Booths controller:
def show
#booth = Booth.find(params[:id])
end
I should also include my booth migration:
class CreateBooths < ActiveRecord::Migration
def change
create_table :booths do |t|
t.string :name
t.references :user, index: true
t.timestamps null: false
end
end
end
Thanks a million!

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.

Rails user experience vs file structure with carrierwave and nested forms - Need input on design decisions

I have 2 models, product and a photos model as follows:
product.rb
class Product < ActiveRecord::Base
has_many :photos, dependent: :destroy
accepts_nested_attributes_for :photos, allow_destroy: true
end
photo.rb
class Photo < ActiveRecord::Base
belongs_to :product
validates :album, presence: true
mount_uploader :image, PhotoUploader
end
I'm using carrierwave & s3 for file uploads.
I can nest the forms so that users can upload photos at the same time that they create the product. In this scenario, the photo models are saved before the product model is saved, which leads to a photo file path of something like:
uploads/photos/images/photo_id
But the file structure would make more sense if it was something like:
uploads/product/id/photos/
However, product.id is nil at the time of photo creation.
With that in mind, a few questions:
Does the file structure really matter that much or am I over thinking it?
Should I do something instead where the product is saved first with basic info and then the files are attached on a separate form?
Is there something I'm overlooking like a way to trigger carrierwave to move the files after the product model is saved?
From a UI standpoint is it bad practice to have users go thru a multi-step process (in this case for creating a product)?
My solution to have a path such as uploads/products/id/photos/ is to configure the PhotoUploader as follows:
def store_dir
"uploads/products/#{model.product_id}/images"
end
Just be careful that there are no validations that would cause product_id to be non-existant at the time the store_dir method is called.

Multiple Devise models with unique attributes

Short explanation:
I seek architectural advice and help in implementing multiple Devise models in a single app.
More detailed explanation:
My application needs to perform the following behavior:
There are 3 types of users (Partner, Attendee, Speaker) which have some common fields and some unique ones (also, the fields might have different permissions, i.e. Attendee must have a username whereas the Speaker might have it but they don't have to necessarily fill this field in). And moreover, the different user models must have different associations with other tables in the db.
The users need to be able to log in through single log-in form, but the sign-up forms should be different.
So, my first thought was that I should divide the users by roles using Pundit or declarative_authorization or something, but the users don't really have different roles (i.e. permissions) in the app, they rather have different behavior, they might see different content and stuff, so I continued thinking.
My second though was implementing STI and after reading several articles about it, I tried to do that in code.
I generated a Devise User model by doing rails g devise User and after that ran rails g model Attendee and the same for other two users.
Then, I inherited my models from User:
class Attendee < User
end
My User migration looks like this:
create_table :users do |t|
t.string :first_name
t.string :last_name
t.string :type
# Devise stuff ...
..................
t.timestamps null: false
end
And other migrations are like this:
create_table :attendees do |t|
t.string :username
t.string :company_name
t.boolean :subscription
t.timestamps null: false
end
Now I realize it was wrong to create separate tables.
I had to put all the possible fields into the User table, is that correct?
Because now when I try to create any new Attendee or Speaker or Partner in rails console, all of these three models have the exact same fields, those the User model has.
But if I add all the possible fields in the User model, how would I perform validations on field presence?
I've read quite a few articles and questions here on SO, but still can't really wrap my head around how to implement all that.
Anyway, is that a correct way to do what I need?
Could anybody explain me in a detailed way how I should implement this kind of behavior and functionality from start to finish, and how should I work with the models after having implemented them?
PS: here's the history of my migrations and the whole github repo
Update
Remembered another issue that stopped my from doing just role separation:
How should I sign up the different users with different sign-up forms? Different routes? I cannot make the user choose their role from the combobox.
You can create conditional validation rules based on the role, but the first place you need to address this is in the new/edit User form, only showing the allowed fields dynamically based on the role:
class User < ActiveRecord::Base
validates :company, presence: true, if: :is_company?
def is_company
# check for the role
self.role == 'company'
end
end
UPDATE: You can pass an extra parameter to the same registration form and use that to differentiate the type of form you display. That's the nicest way. You can also create separate methods in the UserController -> def register_user, def register_company, def register_xxxx

ActiveRecord polymorpic model association confusion

I have a rails 4 application whereby I've set up a User model. I want the User to have a has_many association with a user profile model, but here's the catch:
My user profile model needs to be polymorphic - the
User model can have multiple (different) user profiles associated
with it (e.g. ProfileTypeA, ProfileTypeB, ProfileTypeC, etc.)
I want my User model to have one association, say, user_profiles, that
would return the all the user's user profiles associated with it.
I believe I'm on the right track (or am I?), but how would this be accomplished using the rails generator? The part that is most confusing to me, is how to do bullet #2 above.
P.S. I took a look at STI's, but it seems to me that my User model would have to have a hard-association with each user profile type model, which I don't like because it would change the User model with each new user profile type I add to the data model.
You sound on right track,try below
#The polymorphic models
class User
has_many :user_profiles, as: :profileable
end
class UserProfile
belongs_to :profileable, polymorphic: true
end
The Migrations below
#migrations
class CreateUserProfiles < ActiveRecord::Migration
def change
create_table :user_profiles do |t|
t.integer :profileable_id
t.string :profileable_type
t.timestamps null: false
end
add_index :user_profiles, :profileable_id
end
end

using a has many and has one association on the same model

I want my user object to be able to be associated with many addresses, and for one of those addresses to be the primary address.
I'm trying to do this without using a Boolean to denote the primary address, instead using both a has-many and and a has-one association - as per the first approach by PinnyM in the following SO: Rails model that has both 'has_one' and 'has_many' but with some contraints
But I can't seem to get it to work.
My migrations:
class User < ActiveRecord::Migration
def change
create_table(:users) do |t|
t.integer :primary_address_id
t.string :name
end
end
end
class Address < ActiveRecord::Migration
def change
create_table(:addresses) do |t|
t.integer :user_id
t.string :address
end
end
end
My models:
class User
has_many :addresses
has_one :primary_address, :class_name => "Address"
end
class Address
belongs_to :user
has_one :user
end
This allows me to use the has_many association by doing user.addresses but I can't seem to access to has one association. I've tried doing:
user.primary_address
user.addresses.primary_address
user.addresses.primary_address.first
I don't really understand how to set these associations up correctly or how to access them. Would appreciate your help!
Just created models and associations that you are using. I don't see why it is not working in your case, because I can access primary_address. This is the code I am using to access it using rails console. Note: I have created a User and couple of Addresses in advance.
# in case if you have user with id = 1
User.find(1).primary_address
# or another example
User.first.primary_address
I don't think your associations will allow this calls though:
user.addresses.primary_address
user.addresses.primary_address.first