Ruby on Rails: Record Creation from view error - ruby-on-rails

I have an isolated issue.
I have a table that populates from several different models, it creates links to follow to each respective view.
The code that I have made for each link should be the same, but for some reason, the link isn't showing up under 'Baseline'. I've checked the :create methods for each model, and they mimic each other, and the code from the view is also just a copy - so I'm at a loss as to where to look next. I'm sure that the problem is that the create method is failing, but I don't know where/how.
Here is the code from my view (I'm also pasting the code from FollowUp3Week, because it works):
<% if Baseline.where(subject_id: sub.subject_id).first != nil %>
<%= link_to "edit", baseline_path([Baseline.where(subject_id: sub.subject_id).first]) %>
<% else %>
<%= Baseline.create(subject_id: sub.subject_id) %> #I left the equal for the screenshot.
<% end %>
</td>
<td>
<% if FollowUp3Week.where(subject_id: sub.subject_id).first != nil %>
<%= link_to "edit", follow_up3_week_path([FollowUp3Week.where(subject_id: sub.subject_id).first]) %>
<% else %>
<% FollowUp3Week.create(subject_id: sub.subject_id) %>
<% end %>
</td>
And here is the create method from baselines_controller.rb
def create
#baseline = Baseline.new(params[:baseline])
if #baseline.save
flash[:success] = "Baseline added from create method"
redirect_to baselines_url
else
render 'new'
end
end
I'm also attaching an image of what it looks like. If I remove the equal sign from <%=, the cell will be blank.
EDIT. I'm in the process of removing all of my database queries from the view. Thank you for your comments.

You should really get that Baseline.where out of your view and into the model. AR scopes from the view is a serious no-no in Rails.
In your baseline mode you could do something like:
def empty_subject(subject_id)
where(subject_id: subject_id).first != nil
end
Also, it looks like you're passing arrays into baseline_path and follow_up3_week_path.
Ditch the square brackets.

on Baseline model, put this
def display_name
"#{name}" #whatever you like to show including link
end

Related

Rails 6: Render a partial if only I'm using a method from my controller

I have a Users controller, with index, show, edit and destroy methods. In my layouts/ folder, I have a general-purpose user.html.erb layout that renders some partials. These partials are of course producing errors due some of the info isn't available, like #user.name, for example. I've tried to render that partial always when I'm in a def show state, something like:
<% if Users.show %>
<% render "shared/asides/users" %>
<% else %>
Other partials
<% end %>
I've tried several ways and I always get errors. I feel totally lost even trying to find out this on the Rails documentation nothing seems to be indicated there too.
Your problem is, as you say, you're trying to display things associated with a user, like #user.name, but there is no #user.
So why not check for #user before showing the partial? Or if you have a collection of users, I'm guessing #users?
<% if #users %>
<%= render "shared/asides/users" %>
<% else %>
<%= Do something else %>
<% end %>
Of maybe a bit neater:
<%= render (#users ? path/to/partial_a.html.erb : path/to/partial_b.html.erb) %>
You can make a special layout for your action. Then, at the end of action add layout to render.
def show
...
render layout: "custom_layout"
end

Rails - how to write an index view?

I'm having trouble figuring out how to display an index.
In my organisation requests view folder, I have a file called index.html.erb.
In that file, I'm trying to list each organisation request. I've tried each of the following formulations:
<% OrganisationRequest.each do |OrgReq| %>
<% organisation_request.each do |OrgReq| %>
<% #organisation_request.each do |OrgReq| %>
<% #organisation_requests.each do |OrgReq| %>
In each case, I get an error that says:
formal argument cannot be a constant
I thought a constant meant something beginning with a capital letter. 3 of the above attempts don't begin with a capital letter.
It's also confusing to me since in my user index, I have <% User.each %> and I don't get an error message.
Can anyone see what's gone wrong? How do I ask for a list of objects?
If you have your data and view right, you should be able to fix with:
<% #organisation_requests.each do |org_req| %>
...
<% end %>
If we stick Rails conventions, we'd say that, you have a OrganisationRequests controller, has such content.
class OrganisationRequestsController < ApplicationController
...
def index
#your_local_variable = OrganisationRequest.find(...)
end
...
end
That is to say, you need to use, #your_local_variable inside view file.
<% #your_local_variable.each do |o| %>
....
<% end %>
If the variable inside index action is #organisation_requests, use that.

How to show items which belong to the category

I'd like to answer what I'm doing wrong. So, I'm trying to list all products that belong to the category, on the category's page. Here is the code:
<% #product = Product.all%>
<% #product.where("category_id = ?", params[:#category_id]).each do |product| %>
<%= product.title %>
<%end%>
But there is nothing showing up on my page. So, what's wrong?
There is a whole bunch of problems with your code.
1) Read guides for starters.
2) You have to define an instance variable in controller's action, and then in view just use this variable in your loop. I assume, it is index action you have view for. If so,
def index
# this variable will be used in view
#products = Product.where(category_id: params[:id])
end
and then in view
#products.where(category_id: params[:category_id]).each..
Also, Make sure you have in params what you expect (inspect the params if not sure).
3) You do not execute code, so nothing is being output.
In erb to make things being evaluated you either use - or =. You used none of these. Here is how it should look like:
# notice dash at the beginning of the line
<%- #products.each do |product| %>
<%= product.category_id %>
<% end %>
probably you want read :category_id from params, not :#category_id (so it should be params[:category_id], not params[:#category_id]).

Check if user voted acts as votable

I want to make some styling changes if user has voted for a photo, and I used this code (acts_as_votable docs):
<% if current_user.voted_for? #photo %>
<%= link_to like_photo_path(#photo), method: :put do %>
<button>
¡Liked!
</button>
<% end %>
<% else %>
You dont like it yet
<% end %>
But this wont work because it will show "Liked" all the time, even if I didn't click the Like button.
photos controller
def upvote
#photo = Photo.friendly.find(params[:id])
#photo.liked_by current_user
redirect_to user_photo_path(#photo.user,#photo)
end
What can it be wrong?
Add an additional condition in your if statement
<% if current_user.voted_for? #photo && #photo.liked_by current_user %>
# different text
<% elsif current_user.voted_for? #photo %>
<%= link_to like_photo_path(#photo), method: :put do %>
<button>
¡Liked!
</button>
<% end %>
<% else %>
You dont like it yet
<% end %>
This is a pretty common design pattern of basically falling through to the next logical default.
Note that if you find yourself nesting "if" statements, like so
if condition_one
if condition_two
if condition_three
# do something
else
# do something else
end
This is the same as
if condition_one && condition_two && condition_three
# do something
else
# do something else
end
If you find yourself falling into the nested ifs pattern then rethink what you're doing. You may need to decompose the code into a helper method, etc.

if current_user.id = #game.user_id

I have links to the show pages for each game in my project and if the
games user_id matches the id of the currently signed in user then I want
it to display the edit button if they are not then it shouldn't display.
I currently have the following code set but it doesn't work. Every game
has the edit button display. The code is as followed:
<% if current_user.id = #game.user_id %>
<div id="text3"><%= link_to 'Edit', edit_game_path(#game) %></div><br />
<% end %>
Any ideas?
MrDanA's answer is most probably the error, but you may want to make this code better. Checking like that is not the Rails way of doing it. Instead, make a User instance method like :
def has_game?(game)
self.games.exists?(:id => game.id)
end
and then in your view :
<% if current_user.has_game?(#game) %> ...
(can even be better by further delegating exists into the game model, as a scope or so, if you like)
You want ==
So:
<% if current_user.id == #game.user_id %>

Resources