简体   繁体   中英

Rails: display create form from one model into another model view

Sorry if this is a stupid question, I am not a seasoned Rails developer.

From what I understand, the Rails way of doing things is:

  • Create a model.
  • Create a controller for this model, with actions such as create, show, etc.
  • Render these actions through a related view with a corresponding name, such as new.html.erb, show.html.erb, etc.
  • Route the view to the desired URL with the router.

What I don't understand though, is whether or not we can mix two models with each other.

For instance, in our app, we have a User model, a Calendar model and a Post model.

A user has many calendars and a calendar has many posts.

And we need to allow people to:

  • Create a new @calendar from their profile (users#show).
  • Create a new @post from a calendar.

The way we accomplished this was by:

  • Creating a _calendar_form.html.erb form and include it into our user's show.html.erb .
  • Creating a _post_form.html.erb form and include it into our calendar's show.html.erb .

However, we are not sure this is the right / Rails way of doing things and feel like we may be breaking the MVC pattern.

If that is the case, is there a solution to achieve a similar result, but with a more conventional approach?

It's acceptable put a form anywhere, but usually make sure to submit your form to the right endpoint. If calendar and post are in different forms, you would expect to have them posted to CalendarsController and PostsController .

The exception to this is usually when you have a accepts_nested_attributes_for in your model. Eg. if class Calendar had accepts_nested_attributes_for :posts , you would be able to have CalendarsController do Calendar.new(posts: {description: 'Foo'}) and both the calendar and post would be saved at once.

It helps me to first think of REST actions (think your calendar form posting to /calendars , etc.), and the controllers just being a proxy for what you could do on a command-line with the models (create model records, etc.). This approach also makes you think of "fat model/thin controller" and abstract as much as you can within your model.

To create a calendar from user profile, you'd first need to define @calendar in your UsersController show action.

def show
  @calendar = Calendar.new
end

In your form, you can use @calendar , Its same as calling form_for Calendar.new

= form_for @calendar do |f| 
  = hidden_field_tag "user_id", @user.id # passing in user_id as a param

Now in your create action in CalendarsController you can use the user_id params to make calendar belong_to the user.

def create
  calendar = Calendar.new(calendar_params)
  calendar.user_id = params[:calendar][:user_id]
  calendar.save
end

You can also use accept nested_attributes, but the above might explain how MVC and association works. Follow the same approach for the other model. Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM