This is a companion discussion topic for the original entry at https://thoughtbot.com/upcase/videos/intermediate-rails-3
This is a companion discussion topic for the original entry at https://thoughtbot.com/upcase/videos/intermediate-rails-3
Isn’t the reference to shout.content.body
in dashboard/show.html.erb a violation of the law of demeter (and Sandy Mertz’s rules).
I added delegate :body, to: :content
to the shouts model and then changed it to shout.body
in the dashboard/show.html.erb
Now after this, it fails when trying to save the Shout with invalid length. (it fails the validation from TextShout and pass nil to content). Probably missing some validates_associated
So I came about this error on create action a shout. It turns out to he the shout/_shout.html.erb
<%= link_to shout.username, shout.user %> in the video but it should actually look like this
<%= link_to shout.username, users_path(shout.user) %>
Can you post your code?
You should post your code. In rails, when you set up routes for a model through resource with the show action, using in a get request will automatically route to the show with the models id passed. So essentially, if you’re routes are set up correctly, users_path(shout.user) is a redundant way of saying just shout.user. There’s an example shown in the following documentation: ActionView::Helpers::UrlHelper. You’ll see it in the second example, and it’s the documentation, so if you want to read up on it, there you go! Check it out!
Rails.application.routes.draw do
constraints Clearance::Constraints::SignedIn.new do
root to: "dashboards#show"
end
resources :shouts, only: [:create, :show]
root to: "homes#show"
resources :passwords, controller: "clearance/passwords", only: [:create, :new]
resource :session, only: [:create]
resources :users, only: [:create] do
resource :password,
controller: "clearance/passwords",
only: [:create, :edit, :update]
end
get "/sign_in" => "sessions#new", as: "sign_in"
delete "/sign_out" => "sessions#destroy", as: "sign_out"
get "/sign_up" => "users#new", as: "sign_up"
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
_show.html.erb
<div>
<%= link_to shout.username, users_path(shout.user) %>
<%= render shout.content %>
<%= link_to shout do %>
<%= time_ago_in_words(shout.created_at) %> ago
<% end %>
</div>
<br>
The problem is here. You need to make it:
resources :users, only: [:create, :show]
Then you should be able to do
link_to shout.username, shout.user
I hope that helps!
I went through whole example in lesson and I run into one problem. ShoutsController#create
validations for body
are not run, which leads into weird state when Shout
is saved, but TextShout
is not. What is proper way of propagating validations from association in Rails? Do I have to write custom validation method?
Thanks for help.
UPDATE: As most of the times, answer was quite simple I just had to read Rails docs more carefully.
Would someone help me understand why we are using reversible. I’m not quite understanding the directions of migrations. It’s clear to me when we do an additional migration (which I believe is migrating ‘up’) we are creating a record in TextShout and updating the shouts table. What’s happening when we are migrating down? When does that even occur?
I’m having trouble with carrying over the shouts to a text shouts. My migration was successful but when I checked my database they were not in the text shouts table.
What is the difference between the polymorphic association used in this lesson and doing something like:
TextShout has_many :contents, through: :shouts
.
PhotoShout has_many :contents, through: :shouts
.
I’d like to know if this is a different or same approach.
Thanks.
This is called many_to_many relation and what you’re trying to do here is to connect tables like that:
TextShout -- > Shout < -- Content
This could not make sense, and let me show you what that means:
Let’s for example look at a situation, where we have Users and Books. We want to connect them to each other, but many users can have many books and vice-versa. So we are going to connect them by creating a connecting model called UserBook
User -- > UserBook < -- Book
User has_many :books, through: :user_books
What many to many relation is going to achieve you - connect several users to several books by creating an inbetween table in the database.
So in your case it means you are trying to connect several text_shouts to several contents (in essence - a model Content) by creating an inbetween table called ‘shouts’. Which is not doing what we wanted to do.
Thanks. This makes sense. Your last example of polymorphic association is similar to what I’m used to.
One clarification I’d like to request:
- The Shout model includes a line that says
belongs_to :content, polymorphic: true
, I’d expect the TextShout (and later on PhotoShout) to have a line that will be a counterpart to this -has_one :shout, as: content
Please tell me why this corresponding line in the TextShout and PhotoShout aren’t included.