Render Partial Help and Breakdown - mysql

When a person uses:
<%= render user.posts %>
what is happening behind the code that is tells it to search for the partial _post.html.erb and know to pass the a specified user inside the call?
I have seen many example where a partial is called from outside the index, such as:
<%= render partial: "posts", locals: {post: post} %>
But that is different from the example above

render user.posts detects a model/s as a parameter, and searches for /posts/_post.html.erb partial, see here, section 3.4.5.
render :partial => 'xxx/yyy' searches xxx/yyy file in views path app/views, i.e. app/views/xxx/yyy, you can see in which places these views are searched by looking at your rails server console.

Figured out what I was trying to achieve. I knew I was missing some simple.
Inside my show view:
<% #user.posts.each do |post| %>
<%= post.title %>
<% end %>

Related

How to render html.erb partial dynamically depending on the origin of the render call?

I've got a _topbar.html.erb partial with element for that I render from the index of homepage.
I want to call the same partial in other pages, but depending on the endpoint that's rendering it, I want to display a different content.
Is there any way to apply a dynamic content based on the origin of the render on Rails?
One way to do this is by using current_page? So you could do something like:
<!-- _topbar.html.erb -->
<% if current_page?(posts_path) %>
Here are my posts
<% else %>
Check out my <%= link_to "posts page", posts_path %>
<% end %>
(docs are here)

Ruby On Rails: +1 option/vote button error

I'm learning ROR and working on a voting style application, I've got my four tables up and running Users, Questions, Options and Answers and I can write to the Answers table via MySQL and the total votes are displaying so far which is great.
I'm having a problem with getting a +1 button working (eventually it'll be unique per user but for now I just want to see it working).
I'm fairly certain my files are all setup correctly but I'm confused with what to put in my Questions "Show" view for the button, it might be a routes problem as it does say undefined method 'upvote_option_path' - any help would be greatly appreciated! If I've forgotten any files below let me know :-)
Question's Show View:
<% #question.options.each_with_index do |option, index| %>
<p><%= option.option_text %></p>
<p><%= pluralize(option.answers.count, "vote") %><br><br></p>
<p><%= button_to '+1', upvote_option_path(option), method: :post %></p>
<% end %>
Option's Controller upvote:
def upvote
#question = Question.find(params[:question_id])
#option = Option.find(params[:option_id])
Answer.create(user_id: current_user.id, question_id: #question, option_id: #option)
end
Routes file:
resources :questions do
resources :options do
post 'upvote'
end
end
rake routes:
question_option_upvote POST /questions/:question_id/options/:option_id/upvote(.:format) options#upvote
undefined method upvote_option_path
According to your routes, there is no upvote_option_path, it should be question_option_upvote_path. Also the path takes two arguments as keys(:question_id & :option_id), so you need to pass those two to the path.
The below should work
<%= button_to '+1', question_option_upvote_path(#question, option), method: :post %></p>
In rake routes you have this: question_option_upvote, in your view you have this: upvote_option_path. Pretty sure your view should say question_option_upvote_path(option).

Using one '_form.html.erb' partial but have different elements appear for certain views

Is it possible to display certain elements within a partial for a particular view in Rails? For example I'd like the submit button's text to change depending on the view: so if I'm in the new.html.erb I'd like the submit button to appear as, <%= f.submit 'Create Account' %> and <%= f.submit 'Update Account' %> for edit.html.erb. The unconventional way would be to manually add the custom code into the each view but is there a clever way to do this in my _form.html.erb partial?
First of all, I would recommend putting it into the new and edit views. However, you can switch off of params[:action] if you want to. As in
<%= f.submit(((params[:action] == 'new') ? 'Create' : 'Update') + ' Account') %>
Use simple_form with i18n for that. SimpleForm make it automatically.
Example:
<%= simple_form_for(#message) do |f| %>
<%= f.error_notification %>
<%= f.input :title %>
<%= f.input :description %>
<%= f.button :submit, class: "btn btn-primary" %>
<% end %>
I second kdeisz's answer if your intention is to use a single partial. The line he wrote will not be necessary if you use two separate views - You can just use different names on the same button in each view without any need for conditional logic.
To answer your supplemental questions: There is a tradeoff here between future changeability and DRY code. If your new and edit needs will start to differ significantly, you will have a lot of bloated, difficult-to-change conditional logic in your partial if you use it to render major features.
If you keep the views separated, this may repeat a significant amount of code, but it will also make the individual pages easier to change; the functions of each view will be tailored very specifically to the needs of each HTTP verb.
The answer isn't to conform completely to REST or to DRY "just because", but to ask yourself what will result in more work down the road. If your new and edit pages will be basically the same but for a few very minor features, the single partial (DRY) is more practical. If you see them diverging significantly in the future, keep them separated into two views (less DRY but more changeable).
Params. Each request made to Rails will automatically include an action and a controller based on the route the user requests; for example, navigating to /foo/bar might trigger action bar for controller foo, depending on how you've set up config/routes.rb. Rails fills in params[:action] and params[:controller] with these automatically. A good explanation of how this works, and how to access path and request params, can be found here.

Rails page has wrong html

I have a link to a page in the same folder as this page on my rails site:
<%= link_to 'Special Access', 'followers/special_access' %>
However, when I go to this page it shows a different page on that url.
<p id="notice"><%= notice %></p>
<div id="sent">
<p>Your request has been sent</p>
<%= link_to 'Home', followers_path %>
</div>
I tried deleting the page that the html is from, but first of all I need that page and it also gives me an error.
I edited the controller to contain:
def special_access
format.html { redirect_to followers/special_access }
format.json { render :json => #post }
end
instead of
def show
but that still didn't solve the problem.
How do I get the right html to show up on the right page?
If you do not define a route for special_access, rails will just assume the the special_acces part in the path is the :id of the route for the show page (as the urls look like followers/:id).
So first off, in your routes.rb, find the resources :followers and replace with the following:
resources :followers do
collection do
get :special_access
end
end
And now you should best always use the rails path helpers, so your link would become
<% link_to 'Special Access', special_access_followers_path %>
Here I was assuming the special access is on the collection of the followers, if it should be on a specific follower (which seems more logical to me, but I have no idea of course), you should write
resources :followers do
member do
get :special_access
end
end
And your link would become
<% link_to 'Special Access', special_access_followers_path(#follower) %>
I am not quite sure what you want to do in your controller action, I hope you just want to render an html page (because redirecting to the same url seems silly, and your syntax is wrong there too).
Hope this helps.

Rails form multiple views?

I'm looking for a way to have a contact form in the application layout and show it on all pages.
Ideally i'd like to just do a
form_for #contact_us
I've tried creating the instance variable in the application controller but it doesnt seem to be in scope when the layout loads..
(does the layout load before the result of the action??)
I guess id settle for a form_tag.
Whats the ususal way of doing this kinda thing?
Thanks!
You can use a partial. Put the form code (use form_tag) in the partial and render the partial in the layout.
More about partials here.
What data are you assigning to #contact_us? You might consider using form_tag rather than form_for if your form doesn't require a resource.
Set up whatever you need in your application controller...
before_filter :prepare_contact_form
def prepare_contact_form
#contact_us = "The stuff your form needs"
end
Create a partial view containing your form. Assuming form_tag meets your needs, for lack of more information...
<!-- app/views/_contact_form.html.erb -->
<%= form_tag "/contact_us" do %>
<%= #contact_us %>
<%= text_field_tag :from_email %>
<%= text_field_tag :message %>
<%= submit_tag 'Submit' %>
<% end %>
Render the partial in your application layout...
<!-- app/views/layouts/application.html.erb -->
render :partial => "contact_form"
Then handle the request in whichever controller action /contact_us is routed to.