Эй, ребята, это мучает меня всю неделю.Я новичок в Rails, поэтому, пожалуйста, будьте осторожны :)
Моя корневая проблема в том, что я пытаюсь написать сообщение form_for, которое будет использовать автозаполнение на входе, чтобы связать сообщение с Клиентом.База данных ищет client_id, а не текстовое имя.Поэтому я попробовал пользовательскую проверку, которая будет искать текстовое значение и заменять его идентификатором.Мой файл Post.rb имеет это:
class Post < ActiveRecord::Base
belongs_to :client
attr_accessor :client_name
attr_accessible :client_name
before_validation_on_create :validate_client
def validate_client
self.client_id = 1 # just a test
end
def client_exists(passed_name)
return Client.where(:full_name => passed_name).first.blank?
end
end
Но когда я делаю это, ни одна из переменных формы не передается.База данных получает все пустые записи, кроме client_id. Как мне это сделать?Почему мои переменные формы не передаются?Заранее большое спасибо.
Редактировать 1: добавлено определение создания из posts_controller.rb
def create
@post = Post.new(params[:post])
respond_to do |format|
if @post.save
format.html {
redirect_to(posts_url) # redirect_to(@post, :notice => 'Post was successfully created.')
}
format.xml { render :xml => @post, :status => :created, :location => @post }
format.js
else
format.html { render :action => "new" }
format.xml { render :xml => @post.errors, :status => :unprocessable_entity }
end
end
end
Редактировать 2: Благодаря @apneadiving я изменил attr_accesible для включения других атрибутов, и этопередает записи POST в базу данных.
attr_accessible :client_id, :time, :content, :client_name
Но когда я изменяю функцию validate_client для поиска client_id,
def validate_client
passed_name = self.client_name
if client_exists(passed_name)
c = Client.where(:full_name => passed_name).first
self.client_id = c.id
else
errors.add_to_base "Error"
end
end
Это всегда дает мне эту ошибку:
Вызывается идентификатор дляnil, который по ошибке будет равен 4 - если вы действительно хотите идентификатор nil, используйте object_id
Edit 3: вот моя форма сообщения.Я не могу получить значение: client_name должным образом.
<%= form_for(@post) do |f| %>
<%= render 'common/error_messages', :object => f.object %>
<div class="field">
<%= f.label :content %><br />
<%= f.text_area :content, :size => "50x6" %>
</div>
<div class="field">
<div class="sub-field">
<%= f.label :client_name %><br />
<%= f.text_field :client_name, :size => "26" %>
</div>
<div class="sub-field">
<%= f.label :date %><br />
<%= f.text_field(:time, :class => 'date', :size => "10", :value => Date.today.strftime('%m/%d/%Y')) %>
</div>
<div class="sub-field">
<%= f.label :time %><br />
<%= f.time_select :time %>
</div>
</div>
<div class="actions clear">
<%= f.submit %>
</div>
<% end %>
Редактировать 4: решение. Я изо всех сил пытался получить: client_name, потому что мой текст был слишком далеко во вкладках(Первоначально я приватизировал эту функцию, а затем вынул слово «частный»).Модифицированная версия ответа @ apneadiving решила его для меня!
class Post < ActiveRecord::Base
belongs_to :client
attr_accessor :client_name
validate :validate_client
def validate_client
passed_name = self.client_name
unless client = Client.find_by_full_name(passed_name).blank?
self.client_id = Client.find_by_full_name(passed_name).id
else
errors.add(:client_name, "'#{passed_name}' cannot be found.")
end
end
end