Примерно так:
class C
@a = 11
end
делает не создание переменной экземпляра с именем @a
для экземпляров C
.Когда вы нажмете @a = 11
, self
будет сам класс, поэтому @a
будет переменной экземпляра для объекта C
.Если вы поместите вышеупомянутое в irb
и посмотрите на C.instance_variables
, вы увидите это:
>> C.instance_variables
=> [:a]
, но когда вы посмотрите на экземпляр C
:
>> C.new.instance_variables
=> []
Кроме того, переменные экземпляра автоматически создаются при первом использовании и инициализируются как nil
.
Объединение вышесказанного говорит нам о том, что в имеется переменная экземпляра @reply_regex
.класс объект MicropostController
но не в экземплярах.Ваш def create
является методом экземпляра, поэтому он будет использовать переменную экземпляра @reply_regex
;но у вас нет @reply_regex
в качестве переменной экземпляра для MicropostController
объектов, поэтому она будет создана и инициализирована как nil
внутри вашего оператора if
.В результате ваш if
в конечном итоге будет иметь следующий вид:
if @micropost.content =~ nil
и @micropost.content =~ nil
оценятся в nil
и, поскольку nil
ложно в логическом контексте, блок if
никогда не вводится и @micropost.in_reply_to
никогда не присваивается значение.
Вы можете использовать переменную класса для своего регулярного выражения:
@@reply_regex = /(\A@[^@ ]+(@)\w+(\.[a-z]{2,3}){1,2}.*\z)/i
def create
@micropost = current_user.microposts.build(params[:micropost])
if @micropost.content =~ @@reply_regex
#...
, поскольку переменные класса видимы для методов экземпляра или, лучше,просто используйте константу:
REPLY_REGEX = /(\A@[^@ ]+(@)\w+(\.[a-z]{2,3}){1,2}.*\z)/i
def create
@micropost = current_user.microposts.build(params[:micropost])
if @micropost.content =~ REPLY_REGEX
#...
В качестве отступления, я думаю, вам следует перенести проверку ответа на вашу модель.Вы можете использовать обратный вызов before_validation
, чтобы убрать любые начальные и конечные пробелы в content
, извлечь и сохранить ответ на:
class Micropost < ActiveRecord::Base
before_validate :process_content, :if => :content_changed?
#...
private
def process_content
# Strip leading/trailing whitespace from self.content
# Extract the reply-to from self.content and save it in self.in_reply_to
end
end
Преимущество здесь в том, что если содержимое изменяется или создаетсябез прохождения через ваш контроллер (например, миграция, вручную в консоли Rails, некая системная задача, которая уведомляет пользователей о чем-то, ...), вы все равно получаете все.