I have following situation:
In the application there are clients and projects. A client can have many projects and a project belongs to a client. I've created everything with scaffolding and the relationship works. I can create a project with reference on a client.
But now i would like to create a button in the view of a client, which links to the "New Project Form" and pass the current client as param. Due to that the client should be pre set in the form for the new Project.
I tried to do this by passing the param as following:
<%= link_to "New Project", new_project_path(:project => { :client_id => #client.id } ), :class => 'btn btn-primary' %>
But I don't get it how i now could use the param :client_id in the new project form. Or may be there is a other way to do this directly in the project controller.
Thankful for any help!
You should probably use a nested resource perhaps with polymorphic association setup. This way you don't need to pass the client_id. Researching the two topics should help a lot.
Here is what I use with simple form to hide the dropdown if a client is set. The rest is Rails magic if you set up your relationships properly.
<% unless #client %>
<%= f.association :client, prompt: 'Select a client...', label_method: lambda { |client| "#{client.first_name} #{client.middle_name} #{client.last_name}" } %>
<% end %>
Related
This question is regarding Rails 4/postgresql and the app is hosted on Heroku.
I am making a Quiz-functionality on a website and I am wondering on how to implement the forms (using Formtastic) best to make this is easy as possible. I have three models:
Quiz (has_many :quiz_questions), e.g. "Test to see how awesome you are"
QuizQuestion(belongs_to :quiz, has_many :quiz_options). e.g. "1. Which is your favorite color")
QuizOption (belongs_to :quiz_question). e.g. "Blue"
I have set up the forms like this:
<%= semantic_form_for([:admin, #quiz], :url => admin_quiz_path(#quiz.id)) do |f| %>
<%= render 'form' , :f => f %>
<% end %>
where the form looks like this:
<%= f.inputs %>
<h3>Quiz questions</h3>
<%= f.semantic_fields_for :quiz_questions do |qq_f| %>
<%= qq_f.inputs %>
<h4>Quiz options</h4>
<%= qq_f.semantic_fields_for :quiz_options do |qqo_f| %>
<%= qqo_f.inputs %>
<% end %>
<% end %>
<%= f.actions do %>
<%= f.action :submit %>
or go <%= link_to 'back', admin_quizzes_path %>
<% end %>
It seems, however, not to be working the way I want. I expect to be able to see the fields of QuizQuestion and QuizOptions in this form (there are objects for those) but I don't.
More importantly is that I would like to be able to create a New QuizQuestion and subsequently QuizOption in this form. It doesn't necessarily have to be jQuery/ajax or anything but I would like to do it all from this form.
Basically, I would like my workflow to be like:
Create a Quiz and add values to it. Click Create.
Add QuizQuestion number one and add the values to it (like "name label"). Click Create.
Add QuizOption related to QuizQuestion number one, and its "name label". Click create.
Repeat for QuizQuestion/QuizOption until the Quiz is done.
How can I do this?
For your workflow you might have to add accept_nested_attributes_for for the nested resources, this way when creating an object object you can actually create nested children (as long as they fulfill all the validations). This way:
# A quiz :has_many :quiz_questions
#quiz = Quiz.create(...)
with a declaration like:
has_many :quiz_questions
accepts_nested_attributes_for :quiz_questions
in your Quiz model you'll actually be able to create QuizQuestion from the quiz model like:
# using the previously quiz model
quiz.quiz_questions.create(...)
Doing the same for the deeply nested associations will do have the same effect.
Perhaps the reason why you don't see any field on the form is because there is not nested object created. Let me explain. When you create a new Quiz object, in your quizs_controller (or whatever the inflection for quiz is...) you need a:
def new
quiz = Quiz.new()
end
and
def create
Quiz.new(quiz_params)
end
private
def quiz_params
# whitelisted parameters sent along with the form
params.require(:quiz).permit(...)
end
if you actually want to be able to see the fields in the form you'll have to use the build method and actually populate that new object with respective the nested resources.
Note that for this to work with the form you will have to whitelist in the quizzes_controller the right attributes. You can debug the params you receive once you send the new quiz formulary and check that everything is right.
TIP! if you don't want to worry about the JS when adding nested resources dynamically, I recommend you using the cocoon gem
I have a nested form
form_for #post do |f|
f.fields_for #ingredients do |ingredient|
ingredient.text_field :name
end
end
link_to "Add ingredient","#"
This is the basic structure. I want a new name field added when you click on "Add ingredients". As I have to pass ingredient(form builder) for making a new field, I am unable to use ajax. There is no way for me to make a new ingredients object using java script in rails.
I see, people working with link_to_function. But I see that is deprecated.
Can anyone suggest a solution for this?
I have a page that works with various models.
One of the items is "Language", where I select the language and level. But I can only insert a single language. I wonder what the best way to insert a "New" button to add another language, even if the edit page (because even though I need to include in the edit page too)
I'm using accepts_nested_attributes_for and simple_form.
Have tried several solutions but could not find any similar tutorial with what I need.
When you mention you have a page which works with various models, you need to remember views != models. In rails, views are used to show data you have defined in your controllers.
When you ask about inserting a new button to add a new language, this will be entirely dependent on your interface, and how you wish it to work. A good example would be this:
#app/views/languages/_new_lang.html.erb
<%= form_for Language.new, url: language_path do |f| %>
<%= f.text_field :name %>
<%= f.submit "Create" %>
<% end %>
A better way to do this will be to use ajax & render a layout-less element on your page:
#app/views/controller/your_view.html.erb
<%= button_to "Test", new_language_path, remote: true, id: "test" %>
#app/controllers/languages_controller.rb
Class LanaguageController < ActiveRecord::Base
layout Proc.new { |controller| controller.request.xhr? ? false : "application" }
end
#app/assets/javascripts/application.js.erb
$(document).on("ajax:success", "#test", function(data) {
$(data).appendTo("body");
});
This will allow you to send the required data through to your system to create a new language. Can be improved, so if you want to use it please let me know in the comments
This is probably a very simple fix but I've been unable to find an answer just yet.
My application has orders and tasks. Orders have many tasks. When a user clicks new task in the show order view, it passes the order.id:
<%= link_to "New Task", new_task_path(:order_id=> #order.id) %>
The url shows:
/tasks/new?order_id=1
I just don't know how to extract this and use it in my form? I have tried:
<%= f.text_field :order_id, :value => #order_id %>
But it's not working.
You can do:
<%= f.text_field :order_id, :value => params[:order_id] %>
Alternately, capture the value (with params) in the controller and assign it to #order_id there.
You are doing this wrong, which is a big deal in Rails where convention-over-configuration is such an important ideal.
If an order has many tasks, your route should look like this:
/orders/:order_id/tasks/new
And your routes should be configured thusly:
resources :orders do
resources :tasks
end
You should [almost] never find yourself passing around record ids in the query string. In fact, you should almost never find yourself using query strings at all in Rails.
I am trying to implement a "Preview" feature before creating an object for a product. I followed Ryan Bates railscast on doing so, in which he does so by passing a parameter :name with the submit button.
<%= submit_tag 'Preview', :name => 'preview_button' %>
However, it's not working in my case, don't know why, may be because I'm using rails 3, I can't tell, but I do not see any changes when I add :name => 'preview_button' with the submit button. Can anyone suggest me a solution?
Adding Paulo's answer, it might be better to route to different actions based on commit param.
We solved using advanced constraints in rails.
The idea is to have the same path (and hence the same named route & action) but with constraints routing to different actions.
resources :plan do
post :save, constraints: CommitParamRouting.new("Propose"), action: :propose
post :save, constraints: CommitParamRouting.new("Finalize"), action: :finalize
end
CommitParamRouting is a simple class that has a method matches? which returns true if the commit param matches the given instance attr. value.
This available as a gem commit_param_matching.
You need to add two submit buttons with different names
<%= submit_tag 'Submit', :name => 'submit_button' %>
<%= submit_tag 'Preview', :name => 'preview_button' %>
then in your controller you need to check the parameters:
if params[:commit] == "Submit"
# do great stuff
end
if params[:preview] == "Preview"
# preview great stuff
end