One route from nested routes not working - ruby-on-rails-3

I have a User model which has_many :portfolios and each Portfolio has_many :pictures. My routes look like this:
resources :users do
resources :portfolios do
resources :pictures
end
end
Then I try to create a new Portfolio like this:
<%= link_to "new portfolio...", new_user_portfolio_path(current_user) %>
With a form like this:
<%= form_for [current_user, #portfolio], html: { class: "form_settings" } do |f| %>
...
<% end %>
But when I click on "new portfolio..." my URL says /users/12/portfolios/new and I get this error:
No route matches {:action=>"show", :controller=>"portfolios", :user_id=>#<User id: 12, name: "michael", password_digest: "d787f56b080945c1ec0b3343cbf962ca427bb8ef", remember_token: "dL4nPlt0E5azUMemNIvkdg", admin: false, created_at: "2013-03-03 01:18:19", updated_at: "2013-03-03 19:56:28">, :id=>#<Portfolio id: nil, user_id: 12, name: nil, created_at: nil, updated_at: nil>}

I don't think the error is coming from the form to create the portfolio. There must be a link on the /portfolios/new page to add a picture or something like that, and this is what's failing (because the portfolio is a new record).
You need to hide this link when you're on the new page.

Related

Mysql2::Error: Column 'encrypted_password' cannot be null

Rails 5, ruby 2.4.0
Error: rails while running rails test
Mysql2::Error: Column 'encrypted_password' cannot be null
My test: utilities_controller_test.rb
require 'test_helper'
class UsersControllerTest < ActionDispatch::IntegrationTest
test "Has first name vidur" do
get users_update_address_url
assert_equal "vidur", users(:regular).first_name
end
end
My Fixture: users.yml
admin:
id: 1
first_name: admin
last_name: tukaweb
email: 'admin#email.com'
encrypted_password: <% Devise::Encryptor.digest(User, 'password') %>
regular:
id: 2
first_name: vidur
last_name: punj
email: 'vidur.punj#hotmail.com'
encrypted_password: <% Devise::Encryptor.digest(User, 'password') %>
You probably want to print the output of that Ruby code instead of just evaluating it, so you'll want to change your ERB delimiters from the evaluate-only to output.
In other words, change
<% %> to <%= %>
So in your case:
encrypted_password: <%= Devise::Encryptor.digest(User, 'password') %>

Filter drop down list option for grouped_collection_select

This is not a homework. I am doing this to boost my RoR skills.
I have both Manufacturer and Model entity. I have all the relationship setup correctly and user has to choose Manufacturer before choosing Model. I added more functionalities to my application that I created. Now, I would like to filter out the name from the Model dropdown list where the name contains the word (Other).
Example for name attribute in Model entity: F20, F10 (Other), E90.
I would like to filter out the name of the model which contain (Other). SQL Statement would be Model.where.not("name LIKE ?", "%(Other)%"). After the manufacturer is selected, F20 and E90 will be shown. F10 (Other) will be excluded since the name contains the word (Other).
This is what I have for the drop down list form.
<%= bootstrap_form_tag url: '/quotation/tints/generate' do |f| %>
<div class="field">
<%= f.collection_select :manufacturer_id, Manufacturer.order(:name), :id, :name, {:prompt => "Select Manufacturer"} %>
</div>
<div class="field">
<%= f.grouped_collection_select :model_id, Manufacturer.order(:name), :models, :name, :id, :name, {:prompt => "Select Model"} %>
</div>
//Some code here that are not related
<% end %>
What I have tried:
In my tints_controller, this and I have updated my form in order to work with what I have modified.
def quotation
#listmanufacturer = Manufacturer.order(:name)
#listmodel = Model.where.not("name LIKE ?", "%(Other)%")
render 'quotation'
end
My form
<%= bootstrap_form_tag url: '/quotation/tints/generate' do |f| %>
<div class="field">
<%= f.collection_select :manufacturer_id, #listmanufacturer, :id, :name, {:prompt => "Select Manufacturer"} %>
</div>
<div class="field">
<%= f.grouped_collection_select :model_id, #listmanufacturer, #listmodel, :name, :id, :name, {:prompt => "Select Model"} %>
</div>
//Some code here that are not related
<% end %>
However, I received an error like TypeError: nil is not a symbol. I am unable to modify my models_controller since the drop down list is being used a few times in different view. Some views will need the models with the word (Other) and some will not require.
#listmodel is the part that breaks everything. By replacing :models with #listmodel, I am hopping to filter out the models name that contain (Other).
Any help is greatly appreciated!
Note: Up to this point, my application is working correctly. All relationships are setup correctly in model and routes are configured.
UPDATE, more logs
ActionView::Template::Error (#<ActiveRecord::Relation [#<Model id: 1, name: "Kancil Old", manufacturer_id: 1, created_at: "2016-08-14 16:12:24", updated_at: "2016-08-14 16:12:24">, #<Model id: 2, name: "Kancil 04", manufacturer_id: 1, created_at: "2016-08-14 16:12:24", updated_at: "2016-08-14 16:12:24">, #<Model id: 3, name: "Kembara", manufacturer_id: 1, created_at: "2016-08-14 16:12:24", updated_at: "2016-08-14 16:12:24">, #<Model id: 4, name: "Kenari", manufacturer_id: 1, created_at: "2016-08-14 16:12:24", updated_at: "2016-08-14 16:12:24">, #<Model id: 5, name: "Kelisa", manufacturer_id: 1, created_at: "2016-08-14 16:12:24", updated_at: "2016-08-14 16:12:24">, #<Model id: 6, name: "Myvi 05", manufacturer_id: 1, created_at: "2016-08-14 16:12:24", updated_at: "2016-08-14 16:12:24">, #<Model id: 7, name: "Rusa", manufacturer_id: 1, created_at: "2016-08-14 16:12:24", updated_at: "2016-08-14 16:12:24">, #<Model id: 8, name: "Viva", manufacturer_id: 1, created_at: "2016-08-14 16:12:24", updated_at: "2016-08-14 16:12:24">, #<Model id: 9, name: "Alza", manufacturer_id: 1, created_at: "2016-08-14 16:12:24", updated_at: "2016-08-14 16:12:24">, #<Model id: 10, name: "Myvi Ii", manufacturer_id: 1, created_at: "2016-08-14 16:12:24", updated_at: "2016-08-14 16:12:24">, ...]> is not a symbol nor a string):
6: </div>
7:
8: <div class="field">
9: <%= f.grouped_collection_select :model_id, #listmanufacturer, #listmodel, :name, :id, :name, {:prompt => "Select Model"} %>
10: </div>
11:
12: <div class="field">
app/views/tints/quotation.html.erb:9:in `block in _app_views_tints_quotation_html_erb__1724914643_132263140'
app/views/tints/quotation.html.erb:3:in `_app_views_tints_quotation_html_erb__1724914643_132263140'
app/controllers/tints_controller.rb:47:in `quotation'
Rendering C:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/actionpack-5.0.0/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb within rescues/layout
Rendering C:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/actionpack-5.0.0/lib/action_dispatch/middleware/templates/rescues/_source.html.erb
Rendered C:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/actionpack-5.0.0/lib/action_dispatch/middleware/templates/rescues/_source.html.erb (9.0ms)
Rendering C:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/actionpack-5.0.0/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb
Rendered C:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/actionpack-5.0.0/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (5.0ms)
Rendering C:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/actionpack-5.0.0/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
Rendered C:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/actionpack-5.0.0/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.0ms)
Rendered C:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/actionpack-5.0.0/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb within rescues/layout (539.0ms)
DEPRECATION WARNING: #original_exception is deprecated. Use #cause instead. (called from status_code_with_paginate at C:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/will_paginate-3.1.0/lib/will_paginate/railtie.rb:49)
In my Manufacturer model,
class Manufacturer < ApplicationRecord
//Something here
def listmodel
models.where.not("name LIKE ?", "%(Other)%")
end
end
In my form,
<%= bootstrap_form_tag url: '/quotation/tints/generate' do |f| %>
<div class="field">
<%= f.collection_select :manufacturer_id, Manufacturer.all.order(:name), :id, :name, {:prompt => "Select Manufacturer"} %>
</div>
<div class="field">
<%= f.grouped_collection_select :model_id, Manufacturer.all.order(:name), :listmodel, :name, :id, :name, {:prompt => "Select Model"} %>
</div>
//More code here
<% end %>
Now in my drop down list, model with name containing (Other) will be excluded.

Couldn't find Project with id=1 [WHERE "projects"."deleted_at" IS NULL]

I am using the paranoia gem.
I have a bunch of projects in my database but for somereason they are behaving as if they were deleted. When I navigate to my projects/1 route I get the error:
Couldn't find Project with id=1 [WHERE "projects"."deleted_at" IS NULL]
When I type this in my console:
Project.find(1).deleted_at
I get
nil
What is happening here?
This is my controller show action:
def show
#project = Project.find(params[:id])
#comments = Comment.all.where(:project_id => #project.id)
#updates = ProjectUpdate.all.where(:project_id => #project.id)
end
Error happens on
#project = Project.find(params[:id])
Here are some model Project scopes:
scope :by_category, lambda {|category| {:conditions => {:category_id => category.id}}}
scope :by_npo, lambda {|npo| {:conditions => {:npo_id => npo.id}}}
With Project.find(1) I get:
=> #<Project id: 1, name: "project 1", npo_id: 1, description: "project1 description", location_id:
4, singular_unit: "1", past_tense_action: "past tense action", conversion: #<BigDecimal:7547d78,'0.1
5E1',18(45)>, created_at: "2014-05-13 00:12:33", updated_at: "2014-05-22 01:20:51", future_tense_act
ion: "future tense action", plural_unit: "2", amount1: #<BigDecimal:75475b0,'0.1E2',9(36)>, amount2:
#<BigDecimal:7547520,'0.2E2',9(36)>, amount3: #<BigDecimal:7547490,'0.3E2',9(36)>, min_amount: nil,
other_amount: true, short_description: "project1 short description", featured_image_id: 3, deleted_
at: nil>
From my index page I link to it 2ice(this is the relevant code:
<div class="pj">
<h5><%= link_to project.name, project, :class => "button-link" %> </h5>
<hr />
<div class="index_featured_image">
<%= link_to image_tag(project.get_featured_image, :alt => "Project Title", class: "featured_image"), project %>
</div>
<div class="proj-content">
<p><strong><%= link_to project.npo.name, npo_path(project.npo) %></strong></br>
<%= project.short_description %></p>
</div>
<div>
<p class="project-loc"><i class="footicons fi-marker large"></i> <%= project.location.city_state %></p>
</div>
<div class="text-center">
<%= button_tag :type => "button", :class => "radius" do %>
<%= link_to "View More", project, :class => "button-link" %>
<% end %>
</div>
</div>
Couple guesses and some advice.
First the guesses. If Project.find(params[:id]) calls WHERE "projects"."deleted_at" IS NULL condition on the table, there must be a default_scope call on the Project. Though it's still weird why id prevents the find method from finding the correct project, if it's really not deleted. Let me see that default_scope (or better just post the whole model in a gist) and I might tell a bit more.
Now some advice. It's not really related to the current issue, but I believe, it will make your Rails life a lot easier these days.
Try not to use deprecated syntax, get on with the new one.
E.g. those scope calls should look like this
scope :by_category, ->(category){where(category_id: category.id)}
Don't use .all with .where. You just don't need it. The .where call will return an ActiveRecord::Relation object you are looking for.
Try to reduce the number of instance variables in controllers. For example you can omit the use of the #comments and #updates variables in your show action, provided that you have set the needed associations on the Project model.
has_many :comments
has_many :updates, class_name: ProjectUpdate
Then in the view you can refer to them as #project.comments and #project.updates without the need to store them separately. It will clean up the controller a bit. Also, if you want to ensure that the comments and updates are not lazy-loaded, you can load them together with the project by calling #project = Project.includes(:comments, :updates).find(params[:id]).
Hope that would be helpful. I'll update the answer would I have something more concrete on the problem.

sending specific data into a collection partial

I have a User class with a has_many :messages and a Message class which belongs_to :user. In the Message controller's show action has the corresponding view:
<% if #messages.any? %>
<ol class="microposts">
<%= render partial: 'shared/message', collection: #messages %>
</ol>
<% end %>
And the shared/_message.html.erb template looks like this:
<li id="<%= message.id %>">
<span class="content"><%= message.body %></span>
<% user_id = message.from %>
<% user = User.find(user_id) %>
From: <%= user.name %>
</li>
I feel like the following two lines should be done in the Messages controller from what I read in tutorials on Rails:
<% user_id = message.from %>
<% user = User.find(user_id) %>
But how would I pass each message's corresponding from value (which stores user.id) into the partial?
thanks,
mike
So far i have understood that you have a from column in your messages table which stores the user_id. So if you call message.from it returns the user_id. Then you can do the following
class Message < AR::Base
belongs_to :user, :foreign_key=>'from'
end
In your controller
#messages = Message.all.includes(:user)
#It will load messages and will associated users eager loaded.
Now in your view you can call message.user.name to get the user's name directly. You dont need these following two lines in your view at all
<% user_id = message.from %>
<% user = User.find(user_id) %>
Let me know if ive missed anything.
UPDATE:
Here is what Ive tried with
User Model
class User < ActiveRecord::Base
attr_accessible :age, :name
has_many :sent_messages, :class_name=>'Message', :foreign_key => 'from'
has_many :received_messages,:class_name=>'Message', :foreign_key => 'user_id'
end
#Contains Data:
#<User id: 1, name: "p1", age: 27, ... ...>,
#<User id: 2, name: "p2", age: 25, ... ...
Message Model
class Message < ActiveRecord::Base
attr_accessible :body, :sender, :title, :receipent
belongs_to :sender, :class_name => 'User', :foreign_key => 'from'
belongs_to :receipent, :class_name => 'User', :foreign_key => 'user_id'
end
Now say p1 is sending a message to p2
p1.sent_messages.create(title: "test title", body: "test body", receipent: p2)
#Result:
#<Message id: 1, title: "test title", body: "test body", user_id: 2, from: 1 ... ... >
Now for a message, you can get both sender and receipent directly like
#messages = Message.includes(:sender, :receipent) # You can load only sender or only receipent
#In View
message.sender.name
#OR
message.receipent.name

How to create a nested form in Rails 3 that works? ( I'm getting a routing error. )

I have a Client and ProposalRequest model that look like this:
class Client < ActiveRecord::Base
has_many :proposal_requests
accepts_nested_attributes_for :proposal_requests, :allow_destroy => true
end
class ProposalRequest < ActiveRecord::Base
belongs_to :client
end
In my my routes file, I included the nested routes, as usual.
resources :clients do
resources :proposal_requests
end
And this is my form so far:
-semantic_form_for [Client.new, ProposalRequest.new] do |f|
=f.inputs
=f.buttons
But after this, I'm stuck because of this error.
No route matches {:controller=>"proposal_requests", :client_id=>#<Client id: nil, name: nil, title: nil, organization: nil, street_address: nil, city: nil, state: nil, zip: nil, phone: nil, email: nil, status: "interested", how_you_heard: nil, created_at: nil, updated_at: nil>}
Can anyone help me puzzle out this error?
The problem is that your nested route is meant to add a new ProposalRequest to an existing Client. If you want to create a Client and a ProposalRequest at the same time, you need to just use new_client_path and semantic_form_for #client do |f|.
I would recommend you do the following in your clients_controller:
def new
#client = Client.find(params[:id])
#client.proposal_requests.build
end
And in your view:
semantic_form_for #client do |f|
= f.inputs # fields for client
= f.inputs :name => 'Proposal Request', :for => :proposal_requests do |pf|
= pf.input :some_proposal_request_attribute
= f.buttons
Hope this helps. Make sure to look at all the examples at https://github.com/justinfrench/formtastic and do some trial and error to get your form how you want it.