Rails 3 - Application layout questions
I'm having some difficulties getting my head around Rails' general application layout.
Basically, I am making a web app for football plays. Coaches login and get brought to th开发者_StackOverflowe /coach/index page. On that page they can draw their play and such, using a JavaScript front end. My problem is, in order to save the play, I need to send that JSON to the server, to log it in the right Play database entry.
Is my layout correct, logically? As in, should a coach logging in bring him to that page, and then he draws the plays there and saves them, creates new ones, loads them etc, or should I be doing this on the pages governed by the Play controller?
I want to save the JSON generated by the play drawing engine to the database. What's the best way to go about doing this? All the Rails AJAX tutorials I see are based on simple forms where you set the remote => true property on them and such. How do I make an AJAX POST/GET to the Rails DB without an explicit form, and handle the input?
This is probably down to my lack of Rails know-how (I'm trying to learn as I go), but what, in your more experienced view, is the best way for me to ensure the right plays get shown to the coach who made them? I'm struggling a little in understanding how controllers access things controlled by other controllers. I'm sure there must be some conventions for this kind of thing.
The more I think about it, the more it seems to me that logging in should take you to the /plays directory, and I should be modifying the create and such in there in order to do what I want to do. Thanks in advance.
- Is your layout logical?
/coaches
makes sense as a destination for Coaches that log in. If your application users are only coaches, then even the root makes sense. When a Coach logs in, he's going to some form ofcoaches#show
, but that doesn't mean you're doing something wrong just because the URL is something like/profile
. Not everything needs to adhere to full REST.on the URL side. In the real world, not evernew
action resides on its own little quaint page. If it makes sense to nest a new Play form on the/coaches
page, your URL doesn't need to reflect it.
Controllers control interactions with a resource. From the /coaches
page, you'll still be sending delete play requests to plays#destroy
and validating new plays through plays#create
which can render 'coaches/index' when it fails.
I've never really dealt with AJAX in Rails.
The best way to ensure that Coaches only see their own plays is to scope them through the
Coach has_many :plays
association. The convention in Rails authentication solutions (like Devise) is to provide a methodcurrent_user
which returns an instance of the User model of the user that's current logged in.
Your coaches#index
action could look like:
# Coaches controller
def index
@plays = current_user.plays
end
Then your view could have:
# views/coaches/index.erb
<ul>
<% for play in @plays %>
<li><%= play.name %></li>
<% end %>
</ul>
What you wouldn't do: @plays = Play.where(:user_id => @user.id)
.
It also simplifies and secures other actions. Consider:
@play = current_user.plays.new
@play = current_user.plays.build(:name => "My First Play")
redirect_to @play, :notice => "Success!" if @play.save
current_user.plays.find(params[:id]).destroy
To answer your question added as a comment:
# Coaches controller
def new
@play = current_user.plays.new
end
def create
@play = current_user.plays.build(params[:play]) # @play now already contains the association to the coach that created it.
if @play.save!
redirect_to # somewhere
else
render 'coaches/index'
end
end
- I highly recommend Railscasts if you aren't familiar with them. Even watching episodes on topics you're not going to implement anytime soon will give you good exposure.
- For example, here's a Railscast on Devise. Devise also has decent documentation on Github.
- I recently bought CodeSchool's couse on Rals Best Practices. Even though some of it might be beyond your immediate grasp, it's a resource that you can always revisit. I consult the slides that came with it all the time to look for better ways of doing things.
精彩评论