Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialDave Faliskie
17,793 PointsMaking a "friendship" between a user and another table
Similar to making a friendship I am trying to have a user be linked to an application. so Instead of having two users in a join table I have one user and one app, where the app is a completely different table from the user.
The part I cant figure out is creating two entries into the join table through the request method.
what I have
def self.request(user, app)
transaction do
app_apply1 = create(user: user, app: app, state: 'pending')
app_apply2 = create(user: app, app: user, state: 'requested')
app_apply1.send_request_email
app_apply1
end
end
This doesn't work because for app_apply2 I'm trying to set an application as a user and a user to and application. In the videos they were both users so it wasn't a problem. heres my controller.
def create
if params[:user_app] && params[:user_app].has_key?(:app_id)
@app = JobListing.find(params[:user_app][:app_id])
@user_app = UserApp.request(current_user, @app)
if @user_app.new_record?
flash[:error] = "Sorry, your application can not be processed at this time."
else
flash[:notice] = "Your Application has been sent to " + @app.company_name
end
redirect_to user_path(current_user)
else
flash[:error] = "Company Required"
redirect_to users_path
end
end
app is used in the join table to represent a JobListing, so app is actually a JobListing.
So how do I add the second entry into my join table? Or is there a better way to achieve the same thing using a different method?
Any help would be great! Thanks
1 Answer
Brandon Barrette
20,485 PointsSo you should instead use a has_many: through association. Create a new model called app_users which has the columns user_id, app_id, and state (make this an integer).
Note that enum requires at least Rails 4.1
Then, in your app_users model:
class AppUser < ActiveRecord::Base
belongs_to :user
belongs_to :app
enum state: { pending: 0, requested: 1, accepted: 2 }
Your user model would look like:
class User < ActiveRecord::Base
has_many :app_users
has_many :apps, through: app_users
Your app model would look like:
class App < ActiveRecord::Base
has_many :app_users
has_many :users, through: app_users
This will allow you to call
User.apps (to show all apps for the user) App.users (to show all users for an app)
Then using the state on the app_users model, you could actually write associations for the particular states. For example:
class User
has_many :pending_apps, -> { where app_users: { state: 0 }}, through: :user_apps, source: :app
Hope that helps! Ask away if you need more clarification. Happy coding =)
Dave Faliskie
17,793 PointsDave Faliskie
17,793 PointsThanks for the detailed response! I did have to add another column for the other user (who posted the app) so both could see view the actions on the app. Would you recommend using the
enum state: { pending: 0, requested: 1, accepted: 2 }
Is it better for the database to use numbers instead of strings? What are the pro/cons of using numbers instead of strings?
Brandon Barrette
20,485 PointsBrandon Barrette
20,485 PointsYou definitely want to use the enum integer column if you have Rails > 4.1
Reason is because with strings, you would have to say
But with enum, you can easily say:
There are lots of nifty calls you can make with the enum. I'd check out the documentation here:
http://edgeapi.rubyonrails.org/classes/ActiveRecord/Enum.html
And then a good article here:
http://dev.mikamai.com/post/82355998967/rails-4-1-activerecord-enums
I actually used enums for the friendship model and also put an enum on my user model for user roles. With enum, you can replace the state machine with some quick callbacks.